Universität Stuttgart Fakultät Informatik Prüfer: Prof. Dr.-Ing. U. G. Baitinger Betreuerin: Dipl.-Inf. P. Sagmeister Beginn am: 29. April 1996 Beendet am: 28. Oktober 1996 CR-Klassifikation D.2.1, D.2.10, D.3.2 Studienarbeit Nr. 1564 Bewertung und Analyse der Spezifikationssprache DisCo cand.Inform. Markus Schmid Institut für Parallele und Verteilte Höchstleistungsrechner Breitwiesenstraße 20-22 D-70565 Stuttgart Zusammenfassung Diese Arbeit hat die Analyse und Bewertung des Spezifikationswerkzeugs "DisCo" (Distributed Cooperation) zum Gegenstand. DisCo umfasst eine Spezifikationssprache und eine Testumgebung. Die Testumgebung gestattet es, eine textuell erstellte Spezifikation graphisch darzustellen und auszuführen. Die DisCo-Sprache besitzt objektorientierte und aktionsorientierte Merkmale. Das Ausführungsmodell der DisCo-Sprache beruht auf dem Konzept der "joint-actons". Jointactions sind atomare (in ihrer Ausführung nicht unterbrechbare) Aktionen, an denen mehrere Objekte beteiligt sein können. Objekte sind Instanziierungen von Klassen. Das Schalten einer ausgewählten Aktion, unter Teilnahme eines Satzes von Objekten, führt i.a. zu einer Zustandsänderung der Objekte. Der Programmablauf ergibt sich durch die sequentielle Ausführung von Aktionen. Das Verhalten des spezifizierten Systems wird durch nichtdeterministische Generierung einer Aktionenfolge bestimmt. Die nichtdeterministische Auswahl der jeweils nächsten Aktion und der zugehörigen Teilnehmerobjekte zu einem Berechnungsschritt wird durch die Ausführungsbedingungen, die zu jeder Aktion gehören, eingeschränkt. Die DisCo-Entwickler stellen das Konzept der joint-actions, als Grundlage für Spezifikationen, als Alternative zum prozessorientierten Modell anderer Spezifikationssprachen zur Diskussion. Die Aufgabe dieser Studienarbeit besteht nun darin, herauszuarbeiten, wie auf der Basis dieser Sprache eine Spezifikation von nebenläufigen, miteinander kommunizierenden Einheiten stattfinden kann, wie also komplexes Systemverhalten mit DisCo beschreibbar ist. Dabei wird von Spezifikationssprachen-Charakteristiken, die allgemein zur Evaluation von Spezifikationssprachen dienen können, ausgegangen. Es wurde untersucht, welche Charakteristiken durch DisCo unterstützt werden, welche ermöglicht werden und welche dem SprachenParadigma von DisCo nicht entsprechen. Wichtige Charakteristiken sind die Möglichkeiten zur Formulierung von Nebenläufigkeit und Kommunikation, die Hierarchisierungsmöglichkeiten oder die Techniken zur Angabe von zeitlichen Randbedingungen. Die Analyse orientiert sich zudem an der praktischen Anwendbarkeit der DisCo-Sprache. Um Erfahrung mit DisCoProgrammierung zu sammeln, wurde die Spezifikation einer Aufzugssteuerung erarbeitet. I Inhaltsverzeichnis Inhaltsverzeichnis 1 Ziel der Studienarbeit 1 2 Spezifikationssprache und Werkzeug - DisCo 2 2.1 2.2 2.3 3 Konzepte und Ziele von DisCo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.1 Objektorientiertheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.1.2 Joint Actions, Nichtdeterminismus und Interleaving-Semantik. . . . . . . 5 2.1.3 Ausführbare Spezifikation - Graphische Benutzungsoberfläche . . . . . . 6 2.1.4 TLA - Temporal Logic of Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Programmiersprache DisCo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.1 System-Part und Creation-Part. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.2 Klasse und Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.3 Aktion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2.4 Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 DisCo-Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3.1 Editieren und Compilieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3.2 Graphikausgabe und Benutzerinteraktionen . . . . . . . . . . . . . . . . . . . . 18 2.3.3 Animation und Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.3.4 Prototypische Implementierung des DisCo-Tools . . . . . . . . . . . . . . . . 21 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 22 3.1 Problemanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2 Anforderungsanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2.1 Anforderung aus Benutzersicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.2.2 Anforderung aus Systemsicht. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 Bewertung und Analyse der Spezifikationssprache DisCo II Inhaltsverzeichnis 3.2.3 4 Mechanismen des Aufzugverhaltens . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.3 Beispiel für Aufzugverhalten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.4 Spezifikation und Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.4.1 Klassen und Objekte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.4.2 Aktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.4.3 Komplexe Abläufe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.5 Ausführung der Spezifiktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.6 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 Analyse von DisCo 4.1 4.2 53 Aufstellung der Evaluationskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.1.1 Hardware- und Software-Entwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.1.2 Modelltaxonomie nach Gajski . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.1.3 Modell-Charakteristiken nach Gajski. . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.1.4 Sonstige Kriterien. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.1.5 Anmerkung zu den Kriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Modelle und Charakteristiken von DisCo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.2.1 Nebenläufigkeit, Nichtdeterminismus und Objektorientiertheit . . . . . 59 4.2.2 Kommunikation, Synchronisation und Exceptionhandling . . . . . . . . . 64 4.2.3 Zeit und Parallelität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.2.4 Sonstige Charakteristiken. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 4.3 Bewertung aus Anwendungssicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 4.4 Weiterverwendung einer DisCo-Spezifikation . . . . . . . . . . . . . . . . . . . . . . . . . 79 4.5 Anmerkungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Bewertung und Analyse der Spezifikationssprache DisCo Inhaltsverzeichnis III 5 Zusammenfassung 82 Literatur 83 WWW-Seiten zum Thema 84 Abbildungsverzeichnis 85 Bewertung und Analyse der Spezifikationssprache DisCo 1 1 1 Ziel der Studienarbeit Ziel der Studienarbeit Ziel der Studienarbeit ist die Analyse und Bewertung von DisCo (Distributed Cooperation). Bei DisCo handelt es sich um die prototypische Implementierung eines Spezifikationswerkzeugs. DisCo gestattet es, eine Spezifikation, die in einer DisCo-eigenen, textuellen Programmiersprache erstellt wurde, graphisch zu visualisieren und auszuführen. Die Intention der Entwickler ist es, mit DisCo eine Spezifikationssprache zur Beschreibung von reaktiven Systemen zur Verfügung zu stellen. Im Rahmen dieser Studienarbeit wird als Beispielspezifikation eines reaktiven Systems eine Personenaufzugssteuerung spezifiziert. Während die Einarbeitung in das DisCo-Spezifikationswerkzeug und die Erstellung der Aufzugspezifikation eine Hälfte der Studienarbeit ausmacht, folgt in der zweiten Hälfte die Analyse von DisCo und die Herausstellung der konzeptionellen Möglichkeiten, die DisCo in Hinblick auf Systemspezifikation bietet. Insbesondere ist es ein Ziel dieser Arbeit, die DisCo-Sprache auf vorhandene Merkmale, die in [GVNG94] als „Charakteristiken konzeptioneller Modelle“ dargestellt sind, zu untersuchen. Im folgenden Kapitel 2) wird DisCo als Programmierwerkzeug vorgestellt. Die wichtigsten Merkmale und Konzepte von DisCo werden kurz erläutert. Die Programmiersprachensyntax und die Möglichkeiten zur Ausführung einer Spezifikation unter DisCo werden genauer dargestellt. Daran anschließend, wird in Kapitel 3) das Spezifikationsbeispiel „Aufzugssteuerung “ entwickelt. Der Weg, ausgehend von der Problem- und Aufgabenanalyse, über die Spezifikation, Implementierung, bis hin zur Programmausführung, wird aufgezeigt. In Kapitel 4) findet schließlich die Untersuchung statt, welche Beschreibungsmethoden für Systeme durch die DisCo-Sprache unterstützt oder zumindest ermöglicht werden. Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 2 2 Spezifikationssprache und Werkzeug - DisCo DisCo wurde bis Oktober 1994 im Rahmen des FINSOFT Programms des Technology Development Centre of Finland am Research Institute for Information Technology an der Tampere University of Technology, Finnland, entwickelt. Die DisCo-Software liegt bis heute in einer prototypischen Implementierung vor und stellt ein experimentelles Programmierwerkzeug dar. DisCo umfaßt eine Programmiersprache, einen Compiler zur Übersetzung des DisCo-Quellcodes in eine Lisp-Zwischendarstellung, sowie einen Interpreter zur halbautomatischen Animation der nach Lisp übersetzten Spezifikation. DisCo läuft unter OpenWindows auf Sun-Workstations. An einer Weiterentwicklung des DisCo-Tools wird zur Zeit1 gearbeitet. Um welche Art der Weiterentwicklung es sich handelt, wurde von Entwicklerseite aus nicht klar umrissen. In der jetzigen Version sind einige zusätzliche Funktionen vorgesehen, die noch nicht oder noch nicht vollständig implementiert sind, so die graphische Darstellung einer gesamten Spezifikation auf Grundlage von Statecharts [Hare87]. Es ist darüberhinaus bekannt, daß die DisCo-Sprache im FOCUS-Projekt (Formal and OO-methods for Customer Driven Specifications) im Rahmen des ESSI-Programms (European System and Software Initiative) zur Spezifikation eingesetzt wird [WWW_2], jedoch war auch hier nicht in Erfahrung zu bringen, in welchem Umfang dies geschieht. 2.1 Konzepte und Ziele von DisCo DisCo wurde als eine Spezifikationssprache für reaktive Systeme2 konzipiert. Sie soll dazu dienen, Systeme und deren Umgebung auf einer hohen Abstraktionsebene zu beschreiben. Sie basiert auf dem Ausführungsmodell der Interleaving-Semantik , das durch nichtdeterministische Abfolge von joint-actions realisiert wurde (die Begriffe werden in Kap.2.1.2 erläutert). Das Konzept der joint-actions wurde von Back und Kurki-Suonio entwickelt [BaKS83], [BaKS88a], [BaKS88b]. Joint actions sind atomare Aktionen, an denen eine bestimmte Anzahl von Objekten gemeinsam beteiligt sind. Die Ausführung einer Aktion führt im allgemeinen zu einer Zustandsänderung der Teilnehmer. Das Systemverhalten, das durch ein DisCo-Programm spezifiziert wurde, ergibt sich dann als eine Folge solcher Aktionsausführungen. Der Name DisCo - Distributed Cooperation - leitet sich von der Bedeutung des Konzepts der joint actions für die Spezifikation verteilter Systeme ab. Die DisCo-Sprache bietet auch objektorientierte Eigenschaften. Als objektorientierte Programmiersprache tauchen hier die gängigen Begriffe von Klassen, Instanzen und Methoden sowie Vererbung auf. Im Gegensatz zu Spezifikationssprachen, die zur Beschreibung von Nebenläufigkeit Prozesse zugrundelegen, sind die DisCo-actions Blöcke von Anweisungen, die sequentiell und nicht unterbrechbar ausgeführt werden. Die Nebenläufigkeit von Systemverhalten spiegelt sich im DisCo-Ausführungsmodell in der Menge aller unterscheidbaren Aktionenfolgen wieder, die entsprechend der Spezifikation möglich sind. Bei prozessorientierten Spezifikationssprachen 1.Juli 1996 2.reaktive Systeme stehen in nicht synchron mit dem Programmablauf geschehender Interaktion mit ihrer Umgebung; typischerweise tritt bei reaktiven Systemen Abarbeitung von parallelen Anweisungen auf. Bewertung und Analyse der Spezifikationssprache DisCo 3 2 Spezifikationssprache und Werkzeug - DisCo kann die nebenläufige Abarbeitung mehrerer unterbrechbarer Prozesse durch die verschränkte Ausführung von kleinen, sequentiell abzuarbeitenden, nicht unterbrechbaren Prozessabschnitten veranschaulicht werden. Dieses Ausführungsmodell wird daher als Interleaving-Semantik bezeichnet. Durch immer stärkere Zergliederung der Prozesse in solche Anweisungsabschnitte, wird nebenläufige Abarbeitung auf sequentielle Abarbeitung zurückgeführt, wobei das Verhalten dasselbe bleibt. In DisCo ist somit schon auf Sprachen-Ebene die verschränkte Abarbeitung atomarer DisCo-actions Grundlage für die Verhaltensbeschreibung. Ein Ziel der Entwickler war es, eine einfache Abbildbarkeit ihrer Spezifikationssprache auf eine formale Notation, zur Durchführung von mechanischen Korrektheitsbeweisen, zu gestatten. Die DisCo-Sprache ist so angelegt, daß eine einfache Übertragung einer DisCo-Spezifikation in die formale Schreibweise der TLA (Temporal Logic of Actions) [Lamp94] möglich ist. Da nicht nur die formale, sondern auch die „anschauliche Verifikation“, in Form von graphischer Darstellung und Animation der Spezifikation ein Entwicklerziel war, gibt es im DisCoTool eine Option, die Aktionen und Objekte, die zuvor textuell beschrieben wurden, graphisch zu visualisieren und die Programmausführung „mit der Maus zu steuern“ oder aber automatisch auszuführen. Neben aktionsorientierten und objektorientierten Eigenschaften, enthält die Sprache auch Anleihen aus der System-Beschreibungssprache Statecharts, also zustandsorientierte Beschreibungsmöglichkeiten für Klassen. Klassen können hierarchisch und parallel aufgebaute Datenstrukturen sein. Diese werden textuell beschrieben und sind als Statecharts graphisch darstellbar. Bei der graphischen Darstellung geschieht auch eine Eintragung der Aktionen als Transitionsübergänge. Somit lassen sich die wichtigsten Entwickler-Ziele an die Sprache und das Werkzeug folgenden Realisierungen zuordnen: Tabelle 2-1: DisCo-Entwickler - Ziele Ziel der Entwickler Wurde in DisCo realisiert durch DisCo - Spezifikationssprache Beschreibung von nebenläufigem Verhalten. Ausführungsmodell der joint actions. Klare, einfache Spezifikation von Systemen. Objektorientierte ProgrammiersprachenMerkmale; Statechartsrepräsentation von Klassen. Durchführung von Korrektheitsbeweisen. Einfache Abbildbarkeit der DisCo-Syntax auf TLA. DisCo - Spezifikationstool Spezifikation als Kommunikationsgrundlage zwischen Entwerfer und Kunden. Statechartsrepräsentation der Klassen bzw. Objekte. Bewertung und Analyse der Spezifikationssprache DisCo 4 2 Spezifikationssprache und Werkzeug - DisCo Tabelle 2-1: DisCo-Entwickler - Ziele Ziel der Entwickler Wurde in DisCo realisiert durch Ausführbarkeit der Spezifikation und einfache Veranschaulichung. Graphische Visualisierung und halbautomatische Animation der Spezifikation. 2.1.1 Objektorientiertheit Als objektorientierte Sprache enthält DisCo die typischen Merkmale: Klassen, Instanzen (Objekte), Methoden (Aktionen1) und Vererbung. Ein Objekt ist die Instanziierung einer Klasse. Es wird vor Programmausführung erzeugt und bleibt über die gesamte Laufzeit als Speicherbereich erhalten. Es können beliebig viele Objekte vom gleichen Klassentyp instanziiert werden. Objekte sind Datenstrukturen, die durch die Klassen spezifiziert werden, als solche sind Objekte passive Gebilde, enthalten also selbst keinerlei Ausführungsanweisungen. Ein Objekt besitzt eine bestimmte, auch unendlich große Anzahl von diskreten Zuständen. Der Zusammenhang zwischen Klasse-Objekt-Aktion wird in Abb.2-1 gezeigt: Abbildung 2-1: Beziehung zwischen Klasse - Objekt - Aktion Klassen Objekte Instanziierung atomare Aktionen Teilnahme Aktionsbedingung Zustandsübergänge & Parameteränderungen Aktionsbedingung Zustandsübergänge & Parameteränderungen Innerhalb der Aktionen-Definition wird zunächst in einer Liste festgelegt, von welcher Klasse die Aktionsteilnehmer sein müssen. Diese Teilnehmer-Objekte erhalten für die Zeit der Aktionsteilnahme einen Namen (role)2. Eine DisCo-action umfaßt einen Aktionsbedingungsteil und einen Anweisungsteil. Werden für alle berechtigten Teilnehmer an der Aktion, Objekte gefunden, so daß die Aktionsbedingung erfüllt ist, kann die Aktion ausgeführt werden. Wird eine Aktion ausgeführt, so kann sie den Zustand der teilnehmenden Objekte ändern. Der Zustand aller nicht teilnehmenden Objekte kann weder verändert werden, noch kann deren 1.Im weiteren werden die Begriffe Aktion, action, DisCo-action oft synonym verwendet; wird der Begriff joint-action verwendet, so soll eher das Konzept (i.G. zum Prozess-Konzept), als die syntaktische Realisierung gemeint sein. 2.Im weiteren werden die Begriffe role, Teilnehmername, Teilnehmerbezeichner oft synonym verwendet. Bewertung und Analyse der Spezifikationssprache DisCo 5 2 Spezifikationssprache und Werkzeug - DisCo Zustand abgefragt werden. Ein anderes Kennzeichen der objektorientierten Programmierung, das auch in DisCo zur Verfügung steht, stellt die Vererbung dar. Vererbung in der DisCo-Sprache besteht darin, daß eine Klasse die Datenstruktur einer anderen Klasse, die zu einem früheren Zeitpunkt definiert wurde, erben kann. Die vererbte Klasse (Subklasse) steht dann als Datenobjekt in der neuen Klasse (Superklasse) zur Verfügung und kann als eigenständiges Objekt an Aktionen teilnehmen. Somit wird in DisCo die bottom-up-Programmiermethode ermöglicht. Wie weiter unten noch gezeigt wird, gibt es auch umfangreiche Mechanismen zur top-down-Programmerstellung. 2.1.2 Joint Actions, Nichtdeterminismus und Interleaving-Semantik An einer DisCo-action können gemeinsam mehrere Objekte unterschiedlichen Klassentyps (siehe Mittelteil von Abb.2-1) teilnehmen. Ist der Aktionsbedingungsteil von irgendeiner Auswahl von Objekten von geeignetem Klassentyp erfüllt, so kann diese Aktion durchgeführt werden. In der Regel tritt nun der Fall ein, daß der Bedingungsteil mehrerer Aktionen zum selben Zeitpunkt der Programmausführung erfüllt wird, so daß eine Auswahl der Aktion stattfinden muß, die dann tatsächlich durchgeführt wird. Nach der Auswahl einer Aktion muß eine weitere Auswahl der Objekte stattfinden, die an dieser Aktion teilnehmen sollen. Abb.2-2 zeigt folgendes Szenario: Es gibt drei Aktionen A1, A2 und A3, die Aktionsbedingungen an die Objekte seien derart, daß das Programm mit A1beginnen muß und folgendes gilt: auf A1kann A1, A2 oder A3 folgen. Auf A2 muß A1 folgen, und auf A3 muß ebenfalls A1 folgen: Abbildung 2-2: Beispiel für DisCo-Aktionsreihenfolge 1. A1 A1 2. A1 A1 3. A1 A1 4. A1 5. A1 1 A1 A2 A3 A2 A1 A3 2 A1 3 ... ... ... ... ... Programmschritt In Abb.2-2 sind nun die fünf möglichen Aktionenfolgen bis einschließlich zum dritten Berechnungsschritt zu sehen. Die Betrachtung aller möglicher Kombinationen bis zum vierten bzw. fünften Schritt ergäbe eine Anzahl von 11 bzw. 21 unterschiedlichen Möglichkeiten, usw. Das gesamte Verhalten, das definiert ist als Menge der Zustände aller Objekte pro Programmschritt, wird nun dadurch bestimmt, welche Objekteauswahl für die Teilnahme an den Aktionen A1, A2 und A3 zu jedem Programmschritt getroffen wird. Es geschieht also in zweifacher Hinsicht eine Auswahl, zum einen eine Aktionenauswahl und zum anderen eine Objekteauswahl. Die Vorgehensweise der Aktionen- und Objekteauswahl ist in Abb.2-3 nochmals für den allgemeinen Fall dargestellt. Der gesamte Programmablauf ergibt sich ausgehend von einem Initialisie- Bewertung und Analyse der Spezifikationssprache DisCo 6 2 Spezifikationssprache und Werkzeug - DisCo rungszustand des Programms (0.) durch eine Iteration (3.) über Aktionenauswahl (1.) und Objekteauswahl (2.) und der Ausführung der gewählten Aktion (4.). Abbildung 2-3: Auswahl von Aktionen und Objekten 0. START 3. Auswahl einer Aktion 1. Aktion1 K1 ... Km Aktion2 K1 ... Km Aktion3 K1 ... Km ... Aktionn K1 ... Km Auswahl von Objekten 3. 2. Objekte O1,1...O1,m 4. Objekte O2,1...O2,m ... Aktion schalten Objekte Ol,1...Ol,m 3. In der Regel müssen Auswahlen 1. bzw. 2. getätigt werden. Dies geschieht interaktiv durch den Benutzer oder zufällig durch den DisCo-Interpreter. Nur in Sonderfällen ist genau eine Aktion zum Programmschritt möglich und steht nur genau ein Satz von Objekten für deren Ausführung zur Verfügung. Im Normalfall findet aber eine wirkliche Auswahl statt, und da keine der Aktionen und Objekte vor anderen Aktionen oder Objekten Priorität hat, handelt es sich um eine nichtdeterministische Auswahl. Das Systemverhalten muß nun so spezifiziert sein, daß jede mögliche Auswahl von Objekten und Aktionen so eingeschränkt wird, daß die möglichen Aktionenfolgen alle ein letztendlich korrektes, eben das gewünschte Verhalten des Systems ergeben. Da der Systemzustand zu einem bestimmten Berechnungsschritt von der Art der Verschränkung der vorhergehend ausgewählten und ausgeführten Aktionen abhängt, kann dieses Ausführungsmodell auch als Interleaving-Semantik bezeichnet werden. 2.1.3 Ausführbare Spezifikation - Graphische Benutzungsoberfläche Die Erstellung der Spezifikation geschieht unter DisCo in einer textuellen Programmiersprache, diese wird, wie in Abb.2-4 skizziert, nach Lisp übersetzt: Bewertung und Analyse der Spezifikationssprache DisCo 7 2 Spezifikationssprache und Werkzeug - DisCo Abbildung 2-4: Erstellung und Ausführung einer DisCo-Spezifikation Textuelle Eingabe Interpreter Textuelle Beschreibung (DisCo-Programm) Graphische Ausgabe AKTION1 AKTION4 AKTION2 Compiler Textuelle Beschreibung (Lisp-Programm) AKTION3 OBJEKT1 OBJEKT3 OBJEKT4 OBJEKT2 Auf der Grundlage der Lisp-Repräsentation geschieht dann eine Interpretation des Programms mit graphischer Ausgabe. Auf dieser graphischen Ausgabe hat der Benutzer die Möglichkeit, mit dem Mauszeiger direkt die Programmausführung zu steuern. Er kann das Programm aber auch halbautomatisch durch den Interpreter ausführen lassen, dieses kann mit oder ohne Graphikausgabe geschehen. Es kann also eine reine Simulation des Systemverhaltens oder aber eine Art Animation mit graphischer Ausgabe durchgeführt werden. Die Ausführung ist in der jetzigen Version des DisCo-Tools nur halbautomatisch, da bestimmte Aktionsbedingungen eine Eingabe vom Benutzer erfordern. 2.1.4 TLA - Temporal Logic of Actions Als Grundlage für formale Verifikation der Spezifikation dient in DisCo die Abbildbarkeit der Textsprache DisCo in die formale Sprache TLA [Lamp94]. Allerdings ist nur eine Untermenge des DisCo-Sprachumfangs nach TLA übersetztbar. Der Begriff der Aktion, wie er in TLA auftaucht, findet eine direkte Realisierung durch die Aktion im Sinne von DisCo. Eine TLAAktion umfaßt sowohl Aktionsbedingungsteil als auch Aktionsausführungsteil einer DiscoAktion. Im Rahmen dieser Arbeit wird die Vorgehensweise bei der Abbildung einer DisCoSpezifikation auf TLA-Notation nicht behandelt. Es sei angemerkt, daß diese Übersetzung „von Hand“ geschieht, auch die Durchführung von Korrektheitsbeweisen auf Grundlage der TLA geschieht selbstverständlich nicht mit Hilfe des DisCo-Tools. Die Vorgehensweise bei mechanischer Beweisführung zur Korrektheitsprüfung, ausgehend von DisCo-Spezifikationen, wird in [Kell94] anhand eines Beispiels dargestellt; dort wird ein Token-Ring-Protokoll zunächst in DisCo spezifiziert und anschließend nach TLA übertragen. Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 8 2.2 Programmiersprache DisCo Ein DisCo-Programm besteht aus zwei Teilen, einer Menge von system-parts und einer Menge von creation-parts. Der system-part enthält alle Definitionen der Klassen und Aktionen und kann selbst auf Aktionen und Klassen, die durch andere system-parts definiert wurden zurückgreifen, indem diese Systeme importiert werden. Klassen und Aktionen, die im selben system-part neu definiert wurden oder aber durch Importierung anderer system-parts bekannt sind, können erweitert (extension von Klassen) oder verfeinert (refinement von Aktionen) werden, diese Methoden entsprechen textuellen Einsetzungsschritten auf Quelltextebene (superposition). Durch diese Methoden wird top-down-Programmerstellung unterstützt. Im creation-part findet die Instanziierung der Objekte statt. Sind creation-part und system-part vollständig erstellt, werden beide Teile, die in einer einzigen Datei abgelegt sind, also als Quelltexte aufeinanderfolgen, übersetzt. Es ist anzumerken, daß es in DisCo keine getrennte Übersetzung verschiedener Module gibt. Beim Übersetzungsvorgang in die Lisp-Darstellung werden vom Compiler, falls keine syntaktischen Fehler vorliegen, mehrere Files erzeugt. Eines enthält die System-Beschreibung(en), die anderen enthalten die unterschiedlichen Ausprägungen der Systeme, wie sie durch die creation-parts festgelegt wurden. Zur Ausführung und Animation des Programms wird der Teil mit den Systeminformationen und genau ein Teil mit den creation-Angaben ausgewählt. Es folgt nun eine Übersicht der wichtigsten DisCo-Sprachelemente. Die Syntax und Semantik wird anhand von Schemata oder Beispielen erläutert. Eine Darstellung der DisCo-Syntax findet sich in [JäKS94]. 2.2.1 System-Part und Creation-Part Auf der obersten Ebene eines DisCo-Programms findet die Definition der system- und creation-parts statt. Als Beispiel eine einfache „Aufzug-Spezifikation“ (Schlüsselworte sind hier und im folgenden fett geschrieben): Listing 2-1: system AUFZUG is class KABINE is usw. end KABINE; action FAHREN by K:KABINE is usw. end FAHREN; end AUFZUG; creation RUN_AUFZUG of AUFZUG is new (5) KABINE; end; Es wird ein System mit der Bezeichnung AUFZUG spezifiziert, das System besteht aus einer Klasse mit dem Bezeichner KABINE und einer Aktion FAHREN. Sowohl die Klasse als auch Bewertung und Analyse der Spezifikationssprache DisCo 9 2 Spezifikationssprache und Werkzeug - DisCo die Aktion sind im Beispiel noch nicht weiter spezifiziert - in welcher Form dies geschehen kann, wird in den nächsten beiden Abschnitten dargestellt. Auf den system-part AUFZUG folgt im Beispiel ein creation-part mit Bezeichner RUN_AUFZUG, der sich auf das System AUFZUG bezieht, dort werden 5 Objekte vom Klassentyp KABINE instanziiert. Zu beachten ist, daß den erzeugten Datenstrukturen keine Bezeichner gegeben werden, sie können nur über die Teilnahme an Aktionen und den ihnen dort zugewiesenen Teilnehmernamen referenziert werden. Allgemein findet im system-part, der mit dem Schlüsselwort system eingeleitet wird, dem ein Bezeichner folgt, eine Auflistung aller Klassen und Aktionen statt. Im creation-Teil, eingeleitet durch das Schlüsselwort creation, wird insbesondere festgelegt, wieviele Objekte instanziiert werden, in welchem Anfangszustand sich die Objekte befinden, welche Anfangsparameter und welche konstanten Parameter zu wählen sind und welche konstanten Referenzierungen auf andere Objekte stattfinden. Es können mehrere system-parts und mehrere creation-parts angelegt werden. Ein creation-part bezieht sich immer auf genau einen systempart, es kann allerdings zum selben system-part auch verschiedene creation-parts geben. Erstellung mehrerer creation-parts zum gleichen system-part kann dazu dienen, das spezifizierte System zu unterschiedlichen Zeitpunkten des Entwurfs zu untersuchen. Das wird verständlich, wenn beachtet wird, daß ein System jederzeit durch Importierung anderer systemparts oder durch Erweiterung von Klassen, durch Verfeinerung von Aktionen und durch das Hinzufügen neuer Klassen und Aktion konkretisiert und verfeinert werden kann. 2.2.2 Klasse und Objekt Eine Klasse in DisCo ist prinzipiell wie folgt aufgebaut: Listing 2-2: class Klassen_Name(Const_Param_Name: integer | boolean; usw.) is Var_Param_Name: integer | boolean | Klassen_Namex; usw. state Zustands_Name1_1, Zustands_Name1_2,usw.; state Zustands_Name2_1, Zustands_Name2_2,usw.; extend Zustands_Namex(Const_Param_Name: integer | boolean; usw.) by Var_Param_Name : integer | boolean | Klassen_Namex; usw. state Zustands_Namex_1_1, usw. ; state Zustands_Namex_2_1, usw. ; usw. end Zustands_Namex; usw. end Klassen_Name; Eine Klasse besitzt zunächst einen Bezeichner Klassen_Name, der im folgenden für diese Datenstruktur steht und in Klassen- oder Aktionenbeschreibungen verwendet werden kann. Eine Klasse kann eine Menge konstanter Parameter Const_Param_Name besitzen, deren Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 10 Werte bei der Instanziierung festgelegt werden und dann während der Laufzeit des Programms nicht mehr verändert werden können. Den Namen der konstanten Parameter Const_Param_Name folgt die Angabe des Typs; im Falle der konstanten Parameter sind dies die Typen integer und boolean. Nun folgt die Beschreibung der möglichen Objektzustände. Der Gesamtzustand eines Objekts wird bestimmt durch lokale, variable und konstante Parameter und einer Anzahl diskreter Zustände. Dem Namen eines variablen Parameters Var_Param_Name folgt die Typangabe. Als gültige Typenbezeichner gibt es wiederum integer und boolean, aber nun auch Klassenbezeichner Klassen_Namex. Es ist anzumerken, daß Parameter von Klassentyp nur Referenzen („pointer“) auf Objekte vom Typ einer solchen Klasse darstellen, es wird also nicht tatsächlich eine solche Datenstruktur als Objekt-eigener Speicherbereich angelegt. Wird auf ein Parameter eines Klassentyps im Laufe der Programmausführung zugegriffen, geschieht eine Referenzierung auf ein eigenständiges Objekt, das als solches zuvor auch instanziiert worden sein muß und als Teilnehmer einer Aktion angegeben werden muß. Die Angabe eines variablen Parameters vom Klassentyp ist daher in der praktischen Anwendung etwas zweifelhaft und daher selten. Nach der Definition von Parametern folgt nun die Angabe von Zuständen, eingeleitet vom Schlüsselwort state und einer Liste von Zustandsbezeichnern Zustands_Name1_1 usw. Wie in Listing 2-2 zu sehen, kann das Schlüsselwort state auch mehrmals auftauchen. Zustände, die zu verschieund denen state-Anweisungen gehören (wie z.B. Zustands_Name1_1 Zustands_Name2_1) sind zueinander parallel. Ein weiteres mögliches Konstrukt in der Klassendefinition ist „extend ... by ... end“, dieses stellt die Möglichkeit zur Verfügung, die schon erwähnte Erweiterung von Zuständen durchzuführen. Die Erweiterung eines Zustands führt zu einer Hierarchisierung der Klassendefinition, durch Einführen neuer lokaler Zustandsbezeichner und Parameter. So kann ein beliebiger, vorher schon in einer state-Liste aufgeführter Zustand Zustands_Namex lokal auf dieselbe Weise strukturiert werden, wie eine Klasse selbst; eine Klasse kann daher auch als „oberster Zustand“ aufgefaßt werden. Zustände können zueinander in dreifacher Beziehung stehen, wie Abb.2-5 zeigt, nämlich sequentiell, hierarchisch und parallel. Die graphische Darstellung lehnt sich an Statecharts [Hare87] an - Hierarchie wird durch ineinander verschachtelte, abgerundete Rechtecke mit Namensbezeichnung veranschaulicht, Parallelität wird durch eine gestrichelte Linie zwischen Zuständen veranschaulicht. Teil 1. in Abb.2-5 zeigt eine Klasse mit zwei sequentiellen Zuständen, dies bedeutet, ein Objekt dieser Klasse muß sich in genau einem Zustand S1 oder S2 befinden. Teil 2. zeigt eine Klasse mit vier Zuständen. S1 und S3 bzw. S1 und S4 befinden sich auf unterschiedlicher Hierarchie-Ebene, S1 und S2 sind sequentiell. Dies bedeutet, ein Objekt dieser Klasse muß sich in genau einem Zustand S1 oder S2 befinden, wenn es sich in S2 befindet, dann auch in genau einem Zustand S3 oder S4. Teil 3. zeigt eine Klasse mit sechs Zuständen. S1 und S3 bzw. S1 und S2 befinden sich auf unterschiedlichen Hierarchie-Ebenen, ebenso S4 und S5 bzw. S4 und S6. S1 und S4 sind zueinander parallel. Parallelität bedeutet: ein Objekt dieser Klasse muß sich sowohl in Zustand S1 als auch S4 befinden. Das Objekt befindet sich also in genau einem Zustand S2 oder S3 und in genau einem Zustand S5 oder S6. Bewertung und Analyse der Spezifikationssprache DisCo 11 2 Spezifikationssprache und Werkzeug - DisCo Abbildung 2-5: Anordnung von Zuständen 1. 2. class1 3. class3 class2 S1 S1 S1 S2 S3 S2 S4 S3 S2 S4 S5 S6 Um klar zu machen, welche Bedeutung solche Zustände haben können, hier eine Beispieldefinition der Klasse KABINE, wie sie ganz ähnlich im Laufe dieser Arbeit erstellt wurde, in Abb.2-6: Abbildung 2-6: Beispiel für Klassendefinition - Klasse KABINE KABINE(KABINEN_NUMMER : integer) HALTEND EINGERASTET AUFWÄRTS NICHT EINGERASTET BESCHLEUNIGEND ABWÄRTS FAHREND ABBREMSEND STANDORT : integer Die Bedeutung ist folgende: Jeder Kabine wird zunächst eine Ordnungsnummer gegeben, die zu deren Identifizierung dient, das wird durch den konstanten Parameter KABINEN_NUMMER bewerkstelligt. Nun wird die Kabine so spezifiziert, daß sie bestimmte Bewegungszustände annehmen kann. Während eine Aufzugskabine bremst, beschleunigt usw., kann sie sich nach oben oder unten bewegen, um das zu beschreiben, wurden Zustände parallel angeordnet. Die Kabine befindet sich auf einem bestimmten Stockwerk, auch das muß vermerkt werden, hier im veränderlichen Parameter STANDORT. Ein Zustand der Kabine zu einem Zeitpunkt ist daher das Kreuzprodukt aus {AUFWÄRTS, ABWÄRTS} , {HALTEND, BESCHLEUNIGEND, FAHREND, ABBREMSEND} und einem integer-Wert, der für den Kabinen-Standort steht. Im HALTENDen Zustand kann die Kabine zusätzlich EINGERASTET oder Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 12 NICHT EINGERASTET sein. Der Zustand HALTEND ist daher hierarchisch unterteilt, mit den beiden genannten Unterzuständen. Jedes Objekt besitzt einen Default-Zustand, der bei der Initialisierung des Objekts oder beim Zustandswechsel in einen übergeordneten Zustand angenommen wird. Hierzu ist es notwendig, daß auf jeder Hierarchieebene genau ein UnterZustand als Default-Zustand gekennzeichnet wird. Bei parallelen Zuständen muß auf allen zueinander parallelen Ebenen ein Default-Zustand gewählt werden. Im Beispiel sind dies AUFWÄRTS und HALTEND, und im Zustand HALTEND ist schließlich der Zustand EINGERASTET als Unterzustand von HALTEND Default-Zustand. In DisCo dient ein Stern am Zustandsnamen als Kennzeichnung für den Default-Zustand. Bei der graphischen Darstellung in Abb.2-6 deutet eine dicke Umrandung auf den Default-Zustand hin. Eine entsprechende DisCo-Darstellung für die Klasse KABINE ist somit: Listing 2-3: class KABINE(KABINEN_NUMMER : integer) is STANDORT : integer; state *AUFWAERTS, ABWAERTS; state *HALTEND, BESCHLEUNIGEND, FAHREND, ABBREMSEND; extend HALTEND by state *EINGERASTET, NICHT_EINGERASTET end; end KABINE; Erweiterung (extension) kann nicht nur innerhalb der Klassendefinition geschehen, auch im nachhinein kann eine Klasse (Listing 2-4) oder ein einzelner Klassen-Zustand (Listing 2-5) erweitert werden: Listing 2-4: extend KABINE by state *INNENBELEUCHTUNG_AN, INNENBELEUCHTUNG_AUS; end; Die Erweiterung eines einzelnen Zustandes einer Klasse wird in Listing 2-5 gezeigt. Der Zustand EINGERASTET der Klasse KABINE muß hier durch Angabe des Klassennamens, getrennt durch einen Punkt vom Zustandsbezeichner, angesprochen werden: Listing 2-5: extend KABINE.EINGERASTET by state *VOR_TUERÖFFNEN, NACH_TUERÖFFNEN; end; Die vorherige Klassendefinition (Listing 2-3) bleibt von der Erweiterung unberührt. Würden die drei zuletzt gezeigten Listings, Listing 2-3, Listing 2-4 und Listing 2-5, im Quelltext aufeinanderfolgen, so entspräche dies letztendlich folgender Spezifikation der Klasse KABINE: Bewertung und Analyse der Spezifikationssprache DisCo 13 2 Spezifikationssprache und Werkzeug - DisCo Listing 2-6: class KABINE(KABINEN_NUMMER : integer) is STANDORT : integer; state *AUFWAERTS, ABWAERTS; state *HALTEND, BESCHLEUNIGEND, FAHREND, ABBREMSEND; state *INNENBELEUCHTUNG_AN, INNENBELEUCHTUNG_AUS; extend HALTEND by state *EINGERASTET, NICHT_EINGERASTET extend EINGERASTET by state *VOR_TUERAUS, NACH_TUERAUF; end; end; end KABINE; 2.2.3 Aktion Eine Aktionsdefinition in DisCo ist prinzipiell wie folgt aufgebaut: Listing 2-7: action Aktion_Name(Param_Name: integer | boolean;...) by role_Name1:Klassen_Name1, role_Name2:Klassen_Name2, usw. is when boolquant_Ausdruck do [if boolescher_Ausdruck then Anweisung_Sequenz else Anweisung_Sequenz end;] | [Anweisung_Sequenz] end Aktion_Name; Eine Aktionsdefinition wird eingeleitet durch das Schlüsselwort action, gefolgt vom Bezeichner Aktion_Name. Eine Aktion besitzt optional eine Parameterliste, die dem Aktionsbezeichner folgt. Die Parameterliste besteht aus Bezeichnern für Parameter vom Typ integer oder boolean. Diese Parameter werden bei Ausführung einer Aktion nichtdeterministisch mit Werten belegt, die Werte werden allein durch die Aktionsbedingung (s.u.) eingeschränkt.1 Weiter besitzt jede Aktion eine Liste von Teilnehmerobjekten. Jedes Teilnehmerobjekt ist von einem vorher definierten Klassentyp und erhält für die Zeit der Ausführung der Aktion einen Teilnehmernamen. Die Teilnehmerliste folgt dem Schlüsselwort by 1.Möglich ist auch eine Belegung dieser Parameter durch den Benutzer während der Programmausführung. Wobei dann die Auswertung der Aktionsbedingungen auf Grundlage dieser Werte stattfindet. Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 14 und wird durch is abgeschlossen. Nun folgen die zwei Bereiche Aktionsbedingungsteil und Aktionsausführungsteil. Im Bedingungsteil („when boolquant_Ausdruck do“) der Aktionsbeschreibung können prädikatenlogische Ausdrücke erster Stufe über Objektzustände stehen, welche von links nach rechts ausgewertet werden, bis eine negative Auswertung des Ausdrucks erfolgen kann oder das Ende erreicht ist. Die Ausdrücke sind also boolesche quantifizierte Ausdrücke, wobei u.a. EXIST- und ALL- Quantoren zulässig sind. Quantifizierte Ausdrücke beziehen sich auf die Objektzustände aller Objekte eines Klassentyps (also auch von Nichtteilnehmer-Objekten). Nichtquantifizierte Ausdrücke dürfen sich nur auf die Objektzustände der beteiligten Objekte beziehen. Der Aktionsausführungsteil enthält alle Operationen, die den Objektzustand der Teilnehmer an der Aktion verändern können. Diese Anweisungen werden sequentiell von oben nach unten abgearbeitet. Zu den möglichen Anweisungen gehören Zustandsübergänge, Zuweisungsausdrücke und das Konstrukt „if boolescher_Ausdruck then Anweisung_Sequenz else“ (diese Anweisungen wurden oben zusammenfassend als Anweisung_Sequenz abgekürzt). In der if-Bedingung darf boolescher_Ausdruck keine Quantoren enthalten. Es ist anzumerken, daß innerhalb des Anweisungsteils einer Aktion keinerlei iterative Strukturen zur Ablaufsteuerung (Schleifen, rekursive Funktionsaufrufe o.ä.) möglich sind. Objekte werden referenziert über den Teilnehmername role_Namex und den Bezeichner des Klassendatums (Zustands- oder Parameterbezeichner), getrennt durch einen Punkt; zum Beispiel ausgehend von der Definition der Klasse KABINE aus Listing 2-3, werde folgende Aktion FAHREN spezifiziert: Listing 2-8: action FAHREN by K:KABINE is when K.BESCHLEUNIGEND or K.FAHREND do if K.BESCHLEUNIGEND then ->K.FAHREND; end if; if K.AUFWAERTS then K.STANDORT:=K.STANDORT+1; else K.STANDORT:=K.STANDORT-1; end if; end; Diese Aktion hat als Teilnehmer ein Objekt vom Klassentyp KABINE. Dem KABINE-Objekt wird der Teilnehmername K gegeben. Die Bedeutung der Aktion FAHREN ist folgende: befindet sich eine Kabine im Zustand BESCHLEUNIGEND oder FAHREND so wird entsprechend der Fahrtrichtung (AUFWAERTS oder ABWAERTS) der Kabinenstandort um eins „erhöht“ oder „verringert“. Befindet sich die Kabine im Zustand BESCHLEUNIGEND, so findet zusätzlich ein Wechsel in den Zustand FAHREND statt, in DisCo wird ein Zustandswechsel durch „->“ angedeutet, eine Parameter-Zuweisung durch „:=“. Die Referenzierung eines Parameters geschieht durch Angabe des role-Namens (K) der durch einen Punkt vom Zustandsnamen (K.FAHREND) oder Parameterbezeichner (K.STANDORT) getrennt wird. Bewertung und Analyse der Spezifikationssprache DisCo 15 2 Spezifikationssprache und Werkzeug - DisCo Noch eine Anmerkung zu den Quantoren; diese beziehen sich, wie gesagt, auf alle Objekte eines Klassentyps. Das Konzept der atomaren Aktionen besteht ja darin, ausschließlich auf Objekte zuzugreifen, die in der Teilnehmerliste aufgeführt sind. Bei der Verwendung von Quantoren werden aber natürlich alle Objekte eines Klassentyps referenziert. Somit wird durch Quantoren wieder ein syntaktisches Konstrukt eingeführt, das iterativen Charakter hat und somit Verhaltensbeschreibung wesentlich erleichtert. Hier ein Beispiel für die Verwendung von Quantoren in einer Aktionsbedingung: Listing 2-9: action FAHREN by K:KABINE is when (K.BESCHLEUNIGEND or K.FAHREND) and (all/ T:STOCKWERK_TUEREN | „T gehört zu K“ :: „T ist geschlossen“) do usw. end; Hier wurde die Aktionsbedingung der Aktion FAHREN (Listing 2-8) um eine Bedingung unter Gebrauch eines ALL-Quantors all/ erweitert. Es soll bei einer Fahren-Aktion der Kabine sichergestellt sein, daß alle Objekte T vom Klassentyp STOCKWERK_TUEREN (sprich: alle Stockwerktüren), die zur Kabine gehören, geschlossen sind. Hier wurde eine natürlichsprachliche Formulierung gewählt, es ist aber einfach, diese in DisCo-Syntax umzuschreiben. Das Konstrukt „|“ kann ausgesprochen werden als „für die gilt“, und das Konstrukt „::“ kann ausgesprochen werden als „soll gelten, daß“. Durch die Bedingung, die auf „|“ folgt, wird also aus allen Objekten der Menge (hier STOCKWERK_TUEREN) ein Teilmenge betrachtet. Die Bedingung, die auf „::“ folgt, legt fest, was für die Elemente dieser Teilmenge gelten muß. Bei der Verwendung des all/-Quantors wertet sich der Gesamtausdruck als wahr aus, wenn diese Bedingung für alle Elemente der Teilmenge gilt. Bei der Verwendung des Exist-Quantors (or/) wertet sich der Gesamtausdruck als wahr aus, wenn diese Bedingung für mindestens ein Element aus der Teilmenge gilt. Wie hier zu sehen ist, ist es durch die Verwendung von Quantoren möglich auf alle Objekte einer Klasse „zuzugreifen“, das heißt deren Zustand abzufragen, also auch auf solche Elemente, die nicht durch Zuweisung einer role als Teilnehmerobjekte der Aktion bekannt sind; im Beispiel ist keinem Objekt vom Klassentyp STOCKWERK_TUEREN eine role zugewiesen, dennoch werden alle diese Objekte lesend referenziert. Eine Möglichkeit zur Ergänzung einmal spezifizierter Aktionen bietet DisCo mit der Anweisung refined. Durch refined können Aktionsbedingungen konkretisiert werden, d.h., durch konjunktive Verknüpfung der alten Bedingungen mit neuen Bedingungen, verstärkt werden. Anmerkung: Durch die konjunktive Verknüpfung ist sichergestellt, daß die neuen Anweisungen die vorhergehenden implizieren, was eine Bedingung für den Erhalt der safety-Eigenschaft1 der ursprünglichen Spezifikation darstellt2. Die safety-Eigenschaft bezieht sich auf ganze Berechnungsfolgen. So müssen, in Zusammenhang mit generierten Aktionenfolgen in DisCo, stets (über alle Berechnungsschritte hinweg) die Aktionsbedingungen eingehalten 1.Zum „safety“-Begriff siehe z.B. die Ausführungen in [MaPn92] S.282. 2.An dieser Stelle sollte auf die Notwendigkeit des Erhalts der safety-Eigenschaft bei Einsetzungsschritten, in Zusammenhang der Übertragung von DisCo-Programmen nach TLA, hingewiesen werden. In dieser Arbeit wurde auf diesen Aspekt nicht eingegangen; siehe hierzu z.B. die Ausführungen in [JäKS90/1]. Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 16 werden. Eine logische Formulierung dieses Sachverhalts nennt man safety-Eigenschaft des (System-)Verhaltens. Durch einen Refinement-Schritt können außerdem neue lokale Parameter, Aktionsteilnehmer und Aktionsanweisungen hinzugefügt werden: Listing 2-10: refined FAHREN by ... M:MOTOR is when ... M.K=K and M.OK do usw. ->M.STARTEN; end; Hier wurde die Aktion FAHREN ergänzt, indem ein neuer Teilnehmer vom Klassentyp MOTOR hinzugefügt wurde, seine role lautet M. Die Aktionsbedingung wurde erweitert, indem festgelegt wurde, daß die Aktion nur geschaltet werden darf, wenn die vorigen Bedingungen gelten und zusätzlich die Bedingung, daß der Motor, der zur Kabine gehört (M.K=K) betriebsbereit ist (M.OK). Gilt die neue Aktionsbedingung, so werden alle Anweisungen wie vorher durchgeführt und zusätzlich die Anweisung ->M.STARTEN („Motor starten“). Die Punkte „...“ sind Teil der Syntax und deuten an, daß die vorherigen Definitionen übernommen und mit den neu hinzugefügten verknüpft werden. Würden die beiden Listings Listing 2-9 und Listing 2-10 im Quelltext aufeinanderfolgen, so wäre die Aktion FAHREN folgendermaßen definiert: Listing 2-11: action FAHREN by K:KABINE, M:MOTOR is when (K.BESCHLEUNIGEND or K.FAHREND) and (all/ T:STOCKWERK_TUEREN | „T gehört zu K“ :: „T ist geschlossen“) and M.K=K and M.OK do if K.BESCHLEUNIGEND then ->K.FAHREND; end if; if K.AUFWAERTS then K.STANDORT:=K.STANDORT+1; else K.STANDORT:=K.STANDORT-1; end if; ->M.STARTEN; end; 2.2.4 Assertions Zu Test und Debugging-Zwecken können innerhalb der Klassendefinition oder der Aktionsdefinition Bedingungen eingebaut werden (local assertions), die falls sie verletzt werden, zum Abbruch des Programms führen. Die Syntax ist folgende: Bewertung und Analyse der Spezifikationssprache DisCo 17 2 Spezifikationssprache und Werkzeug - DisCo Listing 2-12: assert boolescher_Ausdruck; Falls dieser Ausdruck innerhalb einer Aktion steht, darf sich der boolesche Ausdruck nur auf Zustände und Parameter von Teilnehmerobjekten beziehen. Falls der Ausdruck innerhalb einer Klasse steht, darf sich der boolesche Ausdruck nur auf lokale Daten der Klasse bzw. des Zustands beziehen. Es gibt außer local assertions noch global assertions. Global assertions formulieren Bedingungen über Klassen, die über die gesamte Laufzeit des Programms erfüllt sein müssen, werden die Bedingungen verletzt, führt das zu einem Programmabruch. Global Assertions sind folgendermaßen aufgebaut: Listing 2-13: assert GA_Bezeichner is boolquant_Ausdruck; Eine global assertion erhält also einen Bezeichner GA_Bezeichner, der während der Ausführung des Programms, bei negativer Auswertung der Bedingung boolquant_Ausdruck, als Information ausgegeben wird. Der Ausdruck boolquant_Ausdruck wird in der Regel ein quantifizierter Ausdruck über die Objekte einer oder mehrerer Klassen sein. Global assertions werden außerhalb von Klassen- und Aktionsdefinitionen in den system-parts definiert, also auf selber Ebene, wie system-parts und creation-parts. 2.3 DisCo-Tool Das DisCo-Tool besteht, wie schon in vorherigen Abschnitten angedeutet, aus Compiler und Interpreter, die von einer graphischen Benutzungsoberfläche aus bedient werden . Alle Funktionen sind durch Aufklappmenüs und Mausklick auf das entsprechende Kommando zu erreichen. Es gibt keine textuelle Kommandosprache. Die Stationen auf dem Weg zur Programmausführung sind schon in Abb.2-4 (S.6) skizziert. Es folgt ein Überblick zur Erstellung des Programmcodes, zum Vorgang des Compilierens in die Lisp-Zwischendarstellung, sowie zur Programmausführung. Eine Zusammenfassung der zur Verfügung stehenden Kommandos des DisCo-Tools bietet [Syst94]1. 2.3.1 Editieren und Compilieren Die Eingabe des textuellen DisCo-Codes wird durch das Tool selbst nicht unterstützt. Es steht kein DisCo-eigener Editor zur Verfügung. Ein externer Texteditor dient dem Zwecke der Codeeingabe. Jede Art der Änderung am Quelltext findet mit diesem Editor statt. Der Compiler gibt bei Syntax-Fehlern die Zeilennummer aus, an welcher der Fehler im Quelltext-File vermutlich auftrat, versehen mit kurzen Fehlerkommentaren. Alle Compiler-Ausgaben und sonstige Textausgabe können protokolliert und als ASCII-Files abgespeichert werden. Hat es bei der Übersetzung des Quelltexts keine Fehler gegeben, liegt eine Repräsentation der Spezi1.Dieses Dokument steht, wie auch andere Dokumente zum Thema „DisCo“, online zur Verfügung ; Ausgangspunkt ist [WWW_1]. Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 18 fikation als Zwischendarstellung in Lisp-Code vor, die eine Programmausführung auf der DisCo-eigenen Interpreterplattform erlaubt. 2.3.2 Graphikausgabe und Benutzerinteraktionen Nach der fehlerfreien Übersetzung des DisCo-Quelltextes kann das Lisp-Programm von Interpreter abgearbeitet werden. Hierzu ist es notwendig, zwei Files zu laden, entsprechend der Unterteilung in creation- und system-parts. Der Benutzer kann den Bezeichner des creationparts angeben, der zugehörige system-part wird automatisch ausgewählt. Zusätzlich zu diesen beiden Files wird der Interpreter noch nach einer Datei suchen, die Layout-Informationen über die graphische Darstellung des spezifizierten Systems (Anordnung der Aktions- und ObjektSymbole auf dem Bildschirm) enthält. Eine Layoutdatei liegt zu Anfang nur als Defaultdatei vor, die vorallem bei umfangreichen Systemen noch nicht zu einer sinnvollen Anordnung der Graphikobjekte führt. Um einen Eindruck von der Art der Darstellung zu geben, ist in Abb.2-7 ein Beispiel zu sehen: Abbildung 2-7: Beispiel für DisCo-Graphikausgabe Bewertung und Analyse der Spezifikationssprache DisCo 19 2 Spezifikationssprache und Werkzeug - DisCo Die Bedeutung der Objekte und Aktionen sind hier nicht wichtig.1 Gezeigt wird ein System mit drei Aktionen (RELEASE - GET_WELL - GET_SICK) - dargestellt als rechteckige Kästchen im oberen Bildteil - und elf Objekten von verschiedenem Klassentyp (DOCTOR PATIENT - RECEPTIONIST) - dargestellt als abgerundete Rechtecke auf der restlichen Darstellungsfläche. Zusätzlich ist eine Raute mit der Inschrift GET_SICK zu sehen, das zeigt an, daß augenblicklich eine Aktion mit dieser Bezeichnung ausgeführt wird, im Gegensatz zu den anderen Graphikobjekten verschwindet diese Raute nach der Ausführungszeit der Aktion wieder. Nun zu dem Aufbau und der Darstellungsart der Graphikobjekte. Die Aktionen werden mit Bezeichnern versehen, ebenso die Objekte. Den Objekten wird noch eine Zahl hinzugefügt, die als Ordnungszahl bei der Instanziierung automatisch vergeben wird. In Abb.2-7 gibt es demzufolge fünf Instanzen der Klasse PATIENT, zwei Instanzen der Klasse RECEPTIONIST und vier Instanzen der Klasse DOCTOR und insgesamt elf Objekte. Die Objekte enthalten als Beschriftung zusätzlich Angaben über den aktuellen Objektzustand, der bekanntlich durch Parameterwerte und Zustandsnamen definiert ist, so befinden sich die Objekte PATIENT-1 bis PATIENT-5 im Zustand WELL. Da davon auszugehen ist, daß nicht alle Angaben zum Objektzustand gleich wichtig sind, kann der Benutzer festlegen, welche Angaben angezeigt werden sollen. Die Aktionskästchen sind nochmals unterteilt, die Anzahl der Unterteilungen entspricht der Anzahl der Aktionsteilnehmer. Die eingetragenen Bezeichner sind die Teilnehmernamen und die Klassennamen (sind in Abb.2-7 nicht enthalten), wie sie im Programmtext verwendet wurden. So können an RELEASE drei Objekte mit Teilnehmernamen R, D und P beteiligt sein. Der Benutzer hat nun die Möglichkeit, die Graphikobjekte mit dem Mauszeiger zu verschieben, ihre Größe zu verändern, auf unterschiedliche Arten anzuordnen oder aber ganz auszublenden. In Abb.2-7 wurden also alle Aktionen im oberen Bildteil angeordnet, während drei Reihen Platz für die drei Klassen im unter Teil gewählt wurden. Der Benutzer kann auch entscheiden, ob Objekte, die eine Referenz in Form konstanter Klassen-Parameter zueinander haben, durch Pfeile oder Linien miteinander verbunden werden sollen. In Abb.2-7 „gehört“ also zu jedem RECEPTIONIST eine Anzahl DOCTOR’s. Hat einmal eine geeignete Darstellung der Objekte stattgefunden, kann dieses „Layout“ in der vorher erwähnten Layout-Datei gesichert werden. Eine zweite Art graphischer Darstellung besteht darin, die Objekte als Statecharts zu visualisieren. Die Art der Darstellung, in einem eigenen Fenster, entspricht ungefähr der in Abb.2-6 (S.10) für die Klasse KABINE gezeigten. Dort kann abgelesen werden, in welchem Zustand sich ein Objekt augenblicklich befindet. Es werden auch Angaben zu Transitionsübergängen zwischen den Objektzuständen gemacht. Die Transitionen, die als Pfeile eingezeichnet werden, sind mit Namen von Aktionen versehen, deren Ausführung zu einem Zustandswechsel führen kann. Es können auch mehrere Aktionen mit einer Transition assoziiert werden. Auch in diesem Statecharts-Fenster gibt es die Möglichkeit, das Layout zu verändern. Es ist jedoch bisher nicht möglich, alle Klassen und Aktionen eines Systems in einem gemeinsamen Transitionsdiagramm darzustellen. Neben den Layout-Manipulationen mit Hilfe der Maus, kann nun auch die eigentliche Programmausführung „mausgesteuert“ stattfinden. 1.Es handelt es sich um eine triviale Umsetzung eines Arzt-Sprechstundenhilfe-Patient - Szenarios! Bewertung und Analyse der Spezifikationssprache DisCo 2 Spezifikationssprache und Werkzeug - DisCo 20 2.3.3 Animation und Simulation Dem Ausführungsmodell der Interleaving-Semantik entsprechend, besteht der Programmablauf in der Ausführung einer Folge von Aktionen. DisCo bietet auf der Interpreter-Ebene zwei Möglichkeiten die Aktionenfolge zu generieren, also eine Folge von Aktionen auszuführen. Die Auswahl kann vom System automatisch vorgenommen werden oder aber durch Steuerung durch den Benutzer stattfinden. Die Steuerung des Programms durch den Benutzer findet immer durch Interaktion auf Grundlage der graphischen Ein- / Ausgabe statt, die oben vorgestellt wurde. Ist es Absicht, den Programmablauf automatisch zu „simulieren“, dann kann die Graphikausgabe zum Zwecke der Zeitersparnis ausgeschaltet werden. Außer der Option, die gesamte Graphik auszuschalten, gibt es noch die Möglichkeit einzelne Aktionen und Objekte auszublenden, auch das kann zu einer Geschwindigkeitssteigerung bei der Programmausführung beitragen. Simulation Wird eine reine Simulation, ohne graphische Darstellung beabsichtigt, so geschieht die Anzeige des Programmfortschritts in einem kleinen Textausgabefenster. Die Ausgabe besteht aus einer Sequenz von Aktionsnamen unter Angabe der beteiligten Objekte. Diese Ausgabe kann als Historie in einem ASCII-File gesichert werden und später zu Test- oder Debuggingzwecken nochmals durchlaufen werden. Der Programmablauf endet nach einem entsprechenden Abbruchkommando durch den Benutzer oder aber bei Eintreten eines Deadlocks. Ein Deadlock bezeichnet einen Programmzustand, in dem es nicht mehr möglich ist, eine Aktion zu finden, deren Aktionsbedingungsteil durch irgendwelche Objekte erfüllbar ist. Ein Deadlock kann gewollt oder unbeabsichtigt sein. Das Auftreten eines Deadlock hat zur Folge, daß das interpretierte Programm neu initialisiert werden muß, um die Programmausführung erneut zu starten. Animation Die graphische Animation der Spezifikation geschieht durch Mausklick auf die entsprechenden graphischen Objekte. Auf eine vollständige Benutzereingabe reagiert das System, indem es die ausgewählte Aktion schaltet und danach auf eine erneute Eingabe wartet. Unter „vollständiger Benutzereingabe“ sind hier die aufeinanderfolgenden Auswahlen im Sinne der Iterationsschritte 1. und 2. aus Abb.2-3 (S.5) gemeint. Zu Beginn der Programmausführung prüft der Interpreter, welche der Aktionen aktivierbar sind. Das bedeutet, daß alle Objekte daraufhin untersucht werden, ob sie eine Bedingung irgendeiner Aktion erfüllen, ist das der Fall, so sind diese Aktionen aktivierbar. Alle aktivierbaren Aktionen, werden angezeigt, indem die zugehörigen Symbole in der Graphikausgabe gelb gefärbt werden. Eine „vollständige Benutzereingabe“ besteht nun darin, unter allen aktivierbaren Aktionen eine auszuwählen und für alle Teilnehmerklassen dieser Aktion genau ein Objekt zu selektieren. Auch bei der Objekt-Auswahl wird der Benutzer vom Interpreter unterstützt, indem dieser die möglichen Objekt-Symbole für eine Teilnehmerklasse einfärbt und dem Benutzer so zur Auswahl stellt. Ein Objekt ist für eine Teilnehmerklasse „möglich“, falls es den Aktionsbedingungen der Aktion genügt. Der Benutzer wählt unter den möglichen Objekten eines aus und verfährt für alle übrigen Teilnehmerklassen ebenso. Unter Umständen müssen nicht alle Objekte explizit vom Benutzer angegeben werden, der Interpreter erkennt vielmehr, wann für eine Teilnehmerklasse genau ein Bewertung und Analyse der Spezifikationssprache DisCo 21 2 Spezifikationssprache und Werkzeug - DisCo Objekt möglich ist und wählt dieses automatisch aus. Sind alle Objekte auf diese Weise durch Benutzer und System festgelegt, wird die Aktion automatisch geschaltet. Diesen Programmschritt deutet der Interpreter durch das kurze Aufblinken einer Raute graphisch an. So wurde in Abb.2-7 (S.17) die Aktion GET_SICK unter Teilnahme der Objekte PATIENT-3 und RECEPTIONIST-10 durchgeführt. Neben der reinen benutzergesteuerten Animation, gibt es auch die Möglichkeit, an Aktionen oder an Objekten Breakpoints zu setzen und die Ausführung des Programms automatisch vom Interpreter durchführen zu lassen. In der Regel wird so vorgegangen, daß eine Auswahl von Aktionen und Objekten getroffen wird, deren Ausführung bzw. Teilnahme nicht interessieren, diese werden dann ausgeblendet. Im Graphik-Fenster sind folglich nur noch solche Objektund Aktionssymbole zu sehen, die für den Benutzer relevant sind. An einigen dieser Objekte bzw. Aktionen setzt der Benutzer Breakpoints und läßt dann den Interpreter mit der automatischen Ausführung beginnen. Sobald der Interpreter auf einen Breakpoint trifft (was für einen „Aktion-Breakpoint“ heißt, daß diese Aktion aktivierbar ist, für einen „Objekt-Breakpoint“ heißt, daß dieses Objekt für eine Aktion möglich ist), wird die Programmausführung unterbrochen. Der Benutzer hat die Möglichkeit, nachdem er den Systemzustand inspiziert hat, das Programm „mausgesteuert“ fortzusetzen oder durch den Interpreter weiter automatisch ausführen zu lassen, . Zusammenfassend läßt sich also sagen, daß jeder der beiden Iterationsschritte im Sinne von 1. und 2. aus Abb.2-3 (S.5) entweder durch den Benutzer - interaktiv - oder vom Interpreter automatisch - ausgeführt werden kann; der Benutzer wird bei seiner Auswahl durch den Interpreter unterstützt, indem dieser die möglichen Aktionen und Objekte zu jedem Programmschritt farblich hervorhebt. 2.3.4 Prototypische Implementierung des DisCo-Tools Wie oben besprochen, besteht das DisCo-Tool im wesentlichen aus zwei voneinander relativ unabhängigen funktionalen Teilen: 1. Compiler und 2. Interpreter/Benutzungsoberfläche. Die prototypischen Merkmale der bisherigen DisCo-Version fallen dem Anwender des Tools eher bei der Verwendung der graphischen Benutzungsoberfläche auf. So genügen die Optionen für die Visualisierung und Animation sicher dem, was eine protypische Implementierung erwarten läßt. Eine echte Simulation oder gar ein Test einer Spezifikation kann aber mit dem jetzigen Tool nicht durchgeführt werden. Anmerkungen hierzu finden sich auch in Kap.4.4. Bewertung und Analyse der Spezifikationssprache DisCo 22 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Zum Zwecke der Einarbeitung in das DisCo-Werkzeug und dessen praktischer Anwendung, sollte im Rahmen dieser Arbeit die Spezifikation eines reaktiven Systems ausgearbeitet werden. Als Beispiel für ein solches System diente ein Personenaufzug. Da DisCo nur die Spezifikation abgeschlossener Systeme erlaubt, kann eigentlich nicht die Rede davon sein, daß es sich bei der folgenden Spezifikation um eine Steuerungseinheit für einen Personenaufzug handelt, vielmehr geht es um die Spezifikation des gesamten Aufzugsszenarios, das die üblichen Aktionen und Einheiten eines Personenaufzugs und die Interaktionen zwischen Aufzugbenutzer und Aufzugssteuerung umfaßt. Als solches kann es ganz allgemein als ein interaktives System aufgefaßt werden und besteht, vereinfacht dargestellt, aus drei unterscheidbaren Komponenten, wie in Abb.3-1 zu sehen. Die Einheiten umfassen jeweils passive (Klassen) und aktive Konstrukte (Aktionen), die Aufgabe der Spezifikation ist nun deren korrekte Beschreibung. Zu Abb.3-1: 1. Interaktionsteil: Enthält Aktionen, die der Benutzer des Aufzugs durchführen kann, z.B. Anfordern einer Kabine zur Fahrt in eine bestimmte Richtung. Hierzu bedient er diverse Druckknöpfe; auch eine Lichtschranke kann als Interaktionsobjekt aufgefaßt werden. 2. Aufgabenteil: Enthält Aktionen, die von den Kabinen ausgeführt werden, also z.B. Bremsen, Anfahren, Türen öffnen. 3. Steuerungsteil: Diesem Teil sind alle Aktionen zurechenbar, die der Koordination der Auftragsabarbeitung, sowie der Auftragsbuchhaltung dienen oder, allgemeiner gesprochen, Aktionen, die der Koordination und Steuerung der Kabinen dienen. Hierzu gehören auch Funktionen zur Optimierung des Fahrtwegs. Zum Steuerungsteil sind Objekte zur Buchhaltung zu zählen, wie Pläne, die der Auftragsverwaltung dienen. Abbildung 3-1: Systemkomponenten eines Personenaufzugs Steuerungsteil Aktionen: z.B. EV_AussenauftragSetzen Klassen: z.B. PLAN, AUFTRAG Interaktionsteil Aufgabenteil Aktionen: z.B. Richtungswahl_Aussen Aktionen: z.B. Bremsen Klassen: z.B. RICHTUNGSKNOPF Klassen: z.B. KABINE Bewertung und Analyse der Spezifikationssprache DisCo 23 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Die Trennung der Komponenten Interaktionsteil und Aufgabenteil ist nicht streng. So gibt es Klassen und Aktionen, die gleichzeitig beiden Komponenten zugerechnet werden können: ein Druckknopf ist Interaktionsobjekt (dient der Benutzereingabe) als auch Aufgabenobjekt (kann einen Zustand annehmen, der das System definiert); das Fahren einer Kabine kann als Interaktion mit dem Benutzer, als auch als Aufgabenerledigung durch den Aufzug aufgefaßt werden. Der Steuerungsteil kann relativ klar vom restlichen Teil des Aufzugsystems getrennt werden. Klassen zur Buchhaltungsarbeit sind: PLAN, AUFTRAG. Steuerungsaktionen sind Operationen, die der Fahrtsteuerung der Kabinen und der Einordnung eingehender Aufträge dienen. 3.1 Problemanalyse Die Aufgaben eines Personenaufzugs sind hinlänglich bekannt. Die Arten der Aktionen und Interaktionen sind einfach. Etwas schwieriger zu formulieren sind die Steuerungsmechanismen zur Erfüllung der Aufgaben unter bestimmten Optimierungsbedingungen. Aufzugszenario mit n Stockwerken und k Aufzugskabinen Das Aufzugszenario bestehe aus einer beliebigen Anzahl k von Aufzugschächten mit jeweils einer Kabine, diese Aufzugschächte erstrecken sich über eine ebenfalls variable Anzahl n von Stockwerken. Interaktionen des Benutzers Als mögliche Aktionen des Benutzers sind zu berücksichtigen: Die Anforderung einer Kabine von einem beliebigen Stockwerk aus, zur Fahrt nach oben oder nach unten (Außenauftrag). Sowie die Wahl eines Stockwerks, auf dem die Kabine halten soll, das geschieht innerhalb einer Kabine (Innenauftrag). Hierzu die folgende Skizze: Abbildung 3-2: Auftragsarten beim Personenaufzug ... n Außenauftrag 1 2 3 ... k 3 2 Innenauftrag Die genannten Benutzeraktionen erfordern eine Reaktion des Aufzugsystems wie folgt: Bei Bewertung und Analyse der Spezifikationssprache DisCo 24 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Eingang eines Außenauftrags müssen alle Kabinen zu einer Auftragsabarbeitung in Betracht gezogen werden, folglich muß für die Bekanntgabe des Auftragseingangs bei allen Kabinen gesorgt werden. Bei Innenauftrag ist es einfacher, denn nur die Kabine, von der aus der Auftrag erfolgte, muß sich um dessen Abarbeitung kümmern. Da zu einem Zeitpunkt mehrere Aufträge vorliegen können, die zusätzlich noch von verschiedenen Kabinen alternativ erledigt werden können, muß zur Koordination der Auftragsabarbeitung ein gewisser Buchhaltungsaufwand betrieben werden, der in der Anforderungsanalyse näher beschrieben wird. Aufgaben der Kabine Die Aufgabe der Kabine besteht darin, einen aktuellen Auftrag zu erledigen. Ein aktueller Auftrag wird festgelegt durch eine Stockwerksnummer und die Richtung, in die eine Weiterfahrt erfolgen soll. Die Beschreibung des Verhaltens der Aufzugskabine bei Eingang neuer Aufträge, während der Abarbeitung eines aktuellen Auftrags, wird Gegenstand der Anforderungsanalyse sein. Weitere wünschenswerte Aktionen der Kabine betreffen das Verhalten zur Sicherheitsgewährleistung, also die Reaktion auf unterbrochene Lichtschranken, die an den Kabinentüren angebracht sind, die Überwachung des Gewichts, mit der eine Kabine maximal belastet sein darf, aber auch die Anzeige des momentanen Standorts durch die Stockwerksanzeige, die auf jedem Stockwerk zur Information der wartenden Benutzer vorhanden ist. Außerdem wird der wartende Fahrgast auf dem Stockwerk davon unterrichtet, in welche Richtung sich die Kabine momentan bewegt, um davon abhängig die richtige Kabine auszuwählen. 3.2 Anforderungsanalyse Anforderungen an das Verhalten des Aufzugsystems lassen sich vierfach klassifizieren, siehe Abb.3-3; zum einen muß zwischen Benutzer- und Systemanforderungen1 unterschieden werden (1. und 3.=Benutzer, 2. und 4.=Aufzugsystem), außerdem können sich diese Anforderungen auf die Funktion des Aufzugs im Normalfall (1. und 2.) und im Ausnahmefall (3. und 4.) beziehen: Abbildung 3-3: Vier Aspekte des Systemverhaltens Benutzersicht Systemsicht Normalfall 1. 2. Ausnahmefall 3. 4. Die wichtigsten Anforderungen unter den beiden Sichten „Benutzer“ und „System“ können vereinfacht so formuliert werden: 1.Hier sei unter System ein realer Aufzug gemeint. Bewertung und Analyse der Spezifikationssprache DisCo 25 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 1. Benutzer: Die Bedienung und Erledigung des eigenen Auftrags soll aus Sicht des Aufzugbenutzers so einfach und schnell wie möglich geschehen. Die Interaktionsmöglichkeiten sind, wie in der Problemanalyse beschrieben, vorhanden. 2. System: Aus Sicht des Aufzugsystems soll die Auftragsabarbeitung so geschehen, daß eine minimale Anzahl Richtungswechsel stattfindet und möglichst geringe Fahrtstrecken zurückgelegt werden; wobei unter „Fahrtstrecken“ die Summe der zurückzulegenden Fahrtstrecken aller Kabinen gemeint ist. Hierzu ist zu sagen, daß sich aus der Befriedigung der Anforderung 1. ergibt, daß 2. im allgemeinen nicht optimal erbracht werden kann, denn die schnellst mögliche Erledigung eines einzelnen Auftrags hat in der Regel die Zurückstellung aller anderen Aufträge zur Folge, deren vorherige Ausführung aber aus Sicht des Schutzes der Ressourcen „Fahrtweg“ und „Richtungswechsel“ eventuell vorzuziehen wäre. Auch die beiden Anforderungen, die in 2. formuliert wurden, sind nicht beide gleichzeitig optimal zu erfüllen. Denn ein häufiger Fahrtrichtungswechsel einer Kabine, z.B. bei nahe beeinanderliegenden Auftragsstockwerken, die allerdings nicht auf der momentanen Strecke der Kabine liegen, könnte eventuell zu einer Fahrtweg-optimaleren Erledigung der Aufträge führen. Es ist zu sagen, daß im Rahmen dieser Spezifikation nicht der Anspruch erhoben wird, daß eine optimale Lösungsstrategie des „Aufzugproblems“ im Sinne der Anforderungen vorliegt. Vielmehr wurde auf eine plausible Lösung des Problems ausgewichen, die noch eine verständliche Umsetzung in der natürlichsprachlichen und formalen DisCo-Spezifikation finden konnte. Nun eine detailliertere Anforderungsanalyse. 3.2.1 Anforderung aus Benutzersicht Das Interesse des Aufzugbenutzers ist die sichere und schnellst mögliche Erledigung seiner Aufträge. Im Normalfall (1. Abb.3-3) wird der Benutzer Aufträge erteilen, also eine Kabine in ein bestimmtes, von ihm gewünschtes Stockwerk schicken. Ein Auftrag wird durch Knopfdruck an den Aufzug erteilt. Ein Auftrag kann folgendermaßen erteilt werden: 1. Durch Drücken eines Richtungsknopfes auf einem Stockwerk; hierzu müssen zwei Knöpfe mit Richtungsangaben vorhanden sein; ein Knopf leuchtet auf, wenn er gedrückt wurde, um die Auftragsabarbeitung durch das System anzuzeigen, es können auch beide Knöpfe gedrückt werden. Nochmaliges Drücken eines schon aktivierten, aufleuchtenden Knopfes hat keine Bedeutung für das Systemverhalten. Die Auftragsabarbeitung besteht darin, daß eine Kabine zum betreffenden Stockwerk fährt, dort die Türen öffnet, kurz wartet und die Türen wieder schließt. Die Aktivierung von Richtungsknöpfen ist für alle Kabinen von Bedeutung. 2. Durch Drücken eines Stockwerksknopfes innerhalb einer Kabine; hierzu stehen in jeder Kabine so viele Stockwerksknöpfe zur Verfügung, wie es Stockwerke gibt. Ein Knopf leuchtet auf, wenn er gedrückt wurde, um die Auftragsabarbeitung durch das System anzuzeigen, es können auch mehrere Knöpfe gedrückt werden. Nochmaliges Drücken eines schon aktivierten, auf- Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 26 leuchtenden Knopfes hat keine Bedeutung für das Systemverhalten. Der Knopfdruck innen ist nur für die jeweilige Kabine von Bedeutung. Zur Anzeige der Auftragsabarbeitung steht außer den Knopfanzeigen noch Stockwerksanzeigen zur Information über die momentane Position jeder einzelnen Kabine auf den Stockwerken zur Verfügung. Pro Stockwerk sind also soviel Stockwerkanzeigen zu finden, wie es Kabinen gibt, und jede Anzeige besteht aus so vielen Signallampen, wie es Stockwerke gibt, und es leuchtet jeweils genau eine Signallampe pro Stockwerksanzeige. Soweit zur Auftragserteilung. Zur Auftragsabarbeitung ist nur zu sagen, daß diese von Benutzersicht aus so schnell wie möglich geschehen muß. Für den Ausnahmefall (3. Abb.3-3) stehen zur Gewährleistung der Sicherheit des Benutzers insbesondere ein Notknopf pro Kabine zur Verfügung, dessen Betätigung ein unmittelbares Anhalten der Kabine zur Folge hat. Außerdem stehen ein Türöffnenknopf und ein Türschliessenknopf pro Kabine zur Verfügung, um dem Aufzugfahrer eine gewisse Kontrollmöglichkeit über das ansonsten automatische Öffnen und Schließen der Türen zu geben. Das Schließen der Türen wird außerdem durch eine Lichtschranke überwacht, wird sie unterbrochen, wird die Tür sofort vollständig geöffnet. Weiter sind Sensoren zur Registrierung von Rauchentwicklung und Gewichtsüberschreitung in den Kabinen vorhanden. 3.2.2 Anforderung aus Systemsicht Ziel ist es, das Verhalten des Aufzugs so gut wie möglich, mit den Benutzeranforderungen in Einklang zu bringen. Daher ergibt sich insbesondere das Verhalten des Systems im Ausnahmefall (4. Abb.3-3) unmittelbar aus den Erwartungen des Benutzers an das Systemverhalten. Etwas anderes ist es mit dem Verhalten im Normalfall (2. Abb.3-3). Dort sind Kompromisse notwendig, um die Anforderung des Systems und die Anforderung des Benutzers unter einen Hut zu bringen. (Die letzte Aussage gilt nur für die Auftragsabarbeitung, die Anforderungen an die Möglichkeiten der Auftragsvergabe durch den Benutzer, werden vom Aufzugsystem ebenfalls vollständig unterstützt). Die Anforderung, möglichst schneller Auftragserledigung widerspricht der Anforderung des Systems an einen sparsamen Umgang mit den Ressourcen „Fahrtweg“ und „Richtungswechsel“, wie oben schon bemerkt wurde. Deswegen bedarf es einer Strategie zur Auftragsabarbeitung, die eine möglichst gute Annäherung von Benutzeranforderung und Systemanforderung bringt. Diese Strategie besteht in einer geschickten Buchführung der eingehenden Aufträge und der Vergabe der anstehenden Aufträge an die einzelnen Kabinen. Hier wird die fertige Lösung präsentiert, die Überlegungen die hierzu führten, scheinen im Rahmen dieser Arbeit nicht von allzu großer Bedeutung zu sein. Ein anschauliches Beispiel zur Auftragsvergabe und Auftragsabarbeitung, die nun beschrieben wird, wird in Kap.3.3 gebracht. Auftragsvergabe Ausgehend von Abb.3-2 (S.22) sind zwei Arten von Aufträgen zu unterscheiden. Die Innenaufträge werden von der Kabine, aus der sie stammen abgearbeitet, daher werden solche Aufträge als verbindlich für diese eine Kabine gekennzeichnet. Für Außenaufträge steht zum Bewertung und Analyse der Spezifikationssprache DisCo 27 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Zeitpunkt des Eintreffens des Auftrags noch nicht fest, welche Kabine letztendlich für dessen Erledigung zuständig ist. Erst im Laufe der Kabinenfahrten wird entschieden, welche der Kabinen das Zielstockwerk des Auftrags anfahren soll. (Die Nützlichkeit/Notwendigkeit dieser Strategie läßt sich leicht aus anschaulichen Beispielen ableiten.) Solche Außenaufträge werden daher für alle Kabinen zunächst vorgemerkt. Eintreffende Aufträge werden in Pläne eingetragen, hiervon gibt es pro Kabine drei Arten: einen aktuellen, einen nächsten und einen übernächsten Plan. Das Eintragen eines Auftrags in einen Plan bedeutet, daß zunächst ein Plan ausgewählt wird und danach der Auftrag mit der richtigen Stockwerksnummer bestimmt wird, dieser ausgewählte Auftrag wird dann verbindlich oder vorgemerkt gesetzt. Für die Wahl des Plans entscheidend ist die Fahrtrichtung der Kabine, die Planrichtung des aktuellen Plans, eventuell der Fahrtzustand der Kabine, sowie beim Außenauftrag der Standort der Kabine relativ zum Ort, von woher die Anforderung kommt. Es muß also nach Auftragseingang zunächst der richtige Plan bestimmt werden, dies geschieht nach den in Abb.3-4 und Abb.3-5 dargestellten Schemata. Hier muß nach Außen- und Innenauftrag unterschieden werden . Als Beispiel für einen Innenauftrag, siehe Abb.3-4 - Situation wie Fall 1.: in einer Kabine (angedeutet durch schwarzes Rechteck mit Fahrtrichtungspfeil), die aufwärts fährt, wird ein Zielstockwerk gewählt, das oberhalb des Kabinenstandorts liegt (angedeutet durch den Eck-Pfeil nach oben, rechts der „Kabine“), der aktuelle Plan ist ein Aufwärts-Plan (siehe Legende zu P1, P2 und P3 links oben). Das Schema besagt, welcher Plan ausgewählt wird. Für den Fall 1. wird somit der aktuelle Plan P1 genommen und je nach Stockwerksnummer der zu diesem Plan gehörige Auftrag mit der entsprechenden Stockwerksnummer verbindlich gesetzt. Wie zu sehen ist, wird in den Fällen 3. und 12. von Abb.3-4 noch der Fahrtzustand der Kabine berücksichtigt, deswegen findet dort eine weitere Klassifizierung nach Fahrtzustand der Kabine statt, was durch die Variable x, die in der Legende erklärt wird, geschieht: Abbildung 3-4: Plan-Auswahl bei Innenauftrag P1 aktueller Plan (aufwärts) P2 nächster Plan (abwärts) P3 übernächster Plan (aufwärts) P1 aktueller Plan (abwärts) P2 nächster Plan (aufwärts) P3 übernächster Plan (abwärts) 1. P1 4. P1 7. P1 10. P1 2. P2 5. P1 8. P1 11. P2 3. Px 6. P1 9. P1 12. Px x = 1, falls Kabine FAHREND, ABBREMSEND, EINGERASTET, NICHT EINGERASTET. x = 2, falls Kabine BESCHLEUNIGEND. Bewertung und Analyse der Spezifikationssprache DisCo 28 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Als Beispiel für einen Außenauftrag (relevant für alle Kabinen), siehe Abb.3-5 - Situation wie Fall 1. (bzw. Fall 2.): Betrachtet wird eine Kabine, die aufwärts fährt. Es werde von einem Stockwerk, das oberhalb (bzw. unterhalb) des Kabinenstandorts liegt, eine Kabine nach oben (bzw. unten) angefordert. Der aktuelle Plan ist ein Aufwärts-Plan. Es wird somit der aktuelle Plan P1 (bzw. der nächste Plan P2) genommen, und je nach Stockwerksnummer der zu diesem Plan gehörige Auftrag mit der entsprechenden Stockwerksnummer vorgemerkt gesetzt. Wie zu sehen ist, findet in den Fällen 5. und 24. von Abb.3-5 wiederum eine weitere Klassifizierung nach Fahrtzustand der Kabine statt, was durch die Variable x, die in der Legende erklärt wird, geschieht. Es wird auch klar, weshalb ein dritter Plan benötigt wird. In den Fällen 4. und 21. von Abb.3-5 werden von einem Stockwerk unterhalb (bzw. oberhalb) der Kabine, eine Kabine nach oben (bzw. unten) angefordert, wobei die betrachtete Kabine momentan nach oben (bzw. unten) fährt. Der Auftragswunsch kann folglich erst bei der übernächsten Fahrt berücksichtigt werden, da er für die momentane Fahrt zu „spät“ eingetroffen ist, die nächste Planabarbeitung allerdings in die falsche Richtung gehen würde, siehe hierzu Beispiele in Kap.3.3. In Kap.3.3 wird auch klarer werden, wie die beiden Schemata in Abb.3-4 und Abb.3-5 angewendet werden. Abbildung 3-5: Plan-Auswahl bei Außenauftrag P1 aktueller Plan (aufwärts) P2 nächster Plan (abwärts) P3 übernächster Plan (aufwärts) P1 aktueller Plan (abwärts) P2 nächster Plan (aufwärts) P3 übernächster Plan (abwärts) 1. P1 7. P1 13. P2 19. P2 2. P2 8. P2 14. P1 20. P1 3. P2 9. P2 15. P1 21. P3 4. P3 10. P1 16. P2 22. P2 5. Px 11. P1 17. P2 23. P2 6. P2 12. P2 18. P1 24. Px x = 1, falls Kabine FAHREND, ABBREMSEND, EINGERASTET, NICHT EINGERASTET. x = 3, falls Kabine BESCHLEUNIGEND. Bewertung und Analyse der Spezifikationssprache DisCo 29 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Auftragsabarbeitung Der aktuelle Plan wird nun immer vollständig, ohne Richtungswechsel von einer Kabine abgearbeitet bis sich keine verbindlich oder vorgemerkt gesetzten Aufträge mehr im aktuellen Plan befinden. Die Kabine wird zum Zielstockwerk fahren, das ihrem Standort am nächsten ist und in ihrer momentanen Fahrtrichtung liegt. Dort wird sie anhalten, die Türen öffnen etc. und dann den nächsten Auftrag im aktuellen Plan in Angriff nehmen. Gehen zwischenzeitlich neue Aufträge ein, so werden diese wie in Abschnitt „Auftragsvergabe“ beschrieben, eingeordnet (siehe auch Beispiel in Kap.3.3); Änderungen im aktuellen Plan werden dabei sofort berücksichtigt. Liegt im aktuellen Plan kein Auftrag mehr vor, so wir der nächste Plan genommen und zum aktuellen Plan „ernannt“. Falls der nächste Plan leer ist, wird der übernächste genommen, und wenn dieser ebenfalls keine Aufträge enthält, wird die Kabine am Standort auf neue Aufträge warten. Für den Fall, daß ein nichtleerer Plan gefunden wurde, muß anhand des Richtungsattributs des aktuellen Plans entschieden werden, ob ein Richtungswechsel der Kabine stattfinden soll. Es fällt auf, daß sowohl der Plan, als auch die Kabine ein Richtungsattribut besitzt. Das ist notwendig, da Situationen auftreten können, die eine Anfahrt der Kabine zur Erledigung des ersten Auftrags eines Plans erfordern, die in eine vom Plan verschiedene Richtung stattfindet1. Befindet sich die Kabine nach der Anfahrt im eigentlichen Auftragsstockwerk, wird eine Anpassung der Kabinenfahrtrichtung an die Planrichtung vorgenommen. Was nun die Erledigung eines aktuellen Auftrags anbelangt, so kommt hier ebenfalls die Unterscheidung von verbindlichen und vorgemerkten Aufträgen ins Spiel. Ist eine Auftrag verbindlich (entspricht Innenauftrag), so fährt die Kabine unbedingt zum Zielstockwerk, hält an, öffnet und schließt die Türen und nimmt den nächsten Auftrag in Angriff. Ist ein Auftrag vorgemerkt (entspricht Außenauftrag), so muß im Prinzip vor jeder Kabinenaktion anhand des Systemzustands, der durch den Fahrtzustand aller Kabinen und deren Standorte definiert ist, von neuem entschieden werden, ob die Kabine mit dessen Erledigung fortfahren soll. Das bedeutet, eine Kabine mit einem aktuellen vorgemerkten Auftrag wird in zeitlichen Abständen alle anderen Kabinenzustände inspizieren und dann entscheiden, ob sie den Auftrag abgibt oder mit der Erledigung fortfährt. Hierzu ist anzumerken, daß eine Kabine mit einem aktuellen vorgemerkten Auftrag nicht für andere Kabinen entscheiden kann, ob diese den Auftrag behalten oder nicht, sondern nur für sich selbst. Diese Vorgehensweise sorgt auch dafür, daß niemals zwei Kabinen zum selben Stockwerk, mit selber Fahrtrichtung fahren, um einen vorgemerkten Auftrag auszuführen, denn eine davon ist vom Zielstockwerk weiter oder gleichweit entfernt und wird daher den Auftrag nicht weiterbearbeiten. 3.2.3 Mechanismen der Aufzugssteuerung Im Rahmen dieser Arbeit sollte es weder um eine vollständige Spezifikation eines Aufzugs gehen, noch um die Ausarbeitung von optimalen Fahrtstrategien für Personenaufzüge. Deswegen stellt sich an dieser Stelle sicher die Frage, weshalb so ein aufwendiges Konzept zur Auftragsbearbeitung, wie oben beschrieben, verwendet wurde. Der Grund liegt darin, daß durch die obigen Überlegungen einige wichtige Anforderungen an eine Spezifikation und eine Spezifikationssprache deutlich wurden. Um die Mechanismen zur Spezifikation von Verhaltensan1.Diese Situation tritt in Beispiel Kap.3.3 z.B. zum Zeitpunkt Time=8 bei Kabine 2 auf. Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 30 forderungen unter DisCo geht es in dieser Arbeit aber an erster Stelle. So ist festzustellen, daß sich ein Mechanismus wie Ereignissteuerung (events) zur Realisierung der Anforderungen als wichtig herausgestellt hat. Das ist evident, da die Kabinen in ständigem Informationsaustausch mit ihrer Umgebung stehen müssen, zum Beispiel zum Zwecke optimaler Auftragserledigung. Events lassen sich im allgemeinen in interne und externe Events unterteilen, was allerdings in Zusammenhang mit einer DisCo-Spezifikation nicht sinnvoll ist, da es sich hierbei immer um Beschreibungen abgeschlossener Systeme handelt und nicht um Systeme innerhalb einer Systemumgebung. Events dienen später vorallem zur Synchronisation, um Kommunikation zwischen Kabinen einzuleiten. Zu den Event-auslösenden Aktionen zählen das Drücken von Richtungsknöpfen, Stockwerksknöpfen, Notknöpfen und die Unterbrechung der Lichtschranke. Um die oben angesprochene Kommunikation zu realisieren war es weiter notwendig, einen Broadcast-Mechanismus zu verwenden. Broadcast ist beispielsweise dann notwendig, wenn es darum geht, alle Kabinen vom Eintreffen eines neuen Auftrags zu unterrichten (siehe auch hierzu Beispiel Kap.3.3). Wie die Umsetzung in eine DisCo-Spezifikation stattfindet, ist Gegenstand von Kap.3.4. Zunächst soll in Kap.3.3 das angekündigte Beispiel zur Veranschaulichung des Aufzugverhaltens folgen. 3.3 Beispiel für Aufzugverhalten Auf den Seiten 33 bis 38 wird ein Beispiel für ein Aufzugszenario mit drei Kabinen und sieben Stockwerken in einer graphischen Darstellung gebracht. Jede Seite enthält zwei Szenen zu aufeinanderfolgenden Zeitpunkten. Es soll hiermit das oben vorgestellte Verfahren der Auftragsverwaltung veranschaulicht werden. Auch die Beziehung zwischen Kabine-Plan-Auftrag wird deutlich. Insgesamt findet eine Darstellung zu zwölf Zeitpunkten statt (Time=1 bis Time=12). Jede einzelne der zwölf Szenen gibt Aufschluß über die aktuellen Standorte und die Fahrtrichtungen der Kabinen (Pfeile an den Kabinensymbolen; falls kein Pfeil vorhanden, bedeutet das, daß die Kabine im Haltezustand ist); diese Information läßt sich jeweils aus dem linken Bildteil ablesen. Rechts der gestrichelten Linie befinden sich die Pläne zu jeder Kabine. Pro Kabine gibt es drei Pläne, einen aktuellen, einen nächsten und einen übernächsten. Jeder einzelne Plan hat ebenfalls eine Richtung, die oberhalb des Plans als Pfeil angedeutet ist. Die drei Pläne einer Kabine werden jeweils durch einen schattierten Block repräsentiert. Daher sind auf der linken Seite jeder Szene drei solche Blöcke zu sehen. Ein Block ist in Kästchen unterteilt, wobei jedes Kästchen einem möglichen Auftrag entspricht. Ein Block besteht somit aus 3*7=21 Kästchen, bzw. Aufträgen; das sind für jeden Plan genau soviele Aufträge, wie es Stockwerke gibt. Ein Auftrag kann nicht gesetzt sein (leeres Kästchen), kann verbindlich gesetzt sein (Beschriftung des Kästchens: verbindlich) oder kann vorgemerkt sein (Beschriftung des Kästchens: vorgemerkt). Zur Erinnerung: Ein vorgemerkter Auftrag ist ein Außenauftrag, der für alle Kabinen relevant ist, ein verbindlicher Auftrag ist ein Innenauftrag, der nur von einer Kabine abgearbeitet wird. Ein Auftrag kann in Sonderfällen auch gesteuert sein; dieser Fall wird hier nicht behandelt. Der aktuelle Auftrag einer Kabine wird fett umrandet. Zu beachten ist das Vorrücken der Pläne einer Kabine, und die damit verbundene „Richtungsänderung“ von aktuellem, nächstem und übernächstem Plan, falls sich im aktuellen Plan keine gesetzten Aufträge mehr befinden. Es folgt nun eine kurze Erläuterung der einzelnen Szenen. Bewertung und Analyse der Spezifikationssprache DisCo 31 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Time=1: Kabine 1 befindet sich auf Stockwerk 2, fährt in Abwärtsrichtung nach Stockwerk 0 (verbindlich gesetzter Auftrag). Kabine 2 befindet sich auf Stockwerk 1, fährt in Aufwärtsrichtung nach Stockwerk 5 (vorgemerkt gesetzter Auftrag). Kabine 3 befindet sich auf Stockwerk 3, fährt in Aufwärtsrichtung nach Stockwerk 4 (verbindlich gesetzter Auftrag). Es sind diverse Aufträge in den Plänen eingetragen; zunächst die schon erwähnten fett umrandetet, aktuellen Aufträge, jeweils in den aktuellen Plänen der Kabinen. Kabine 3 hat zusätzlich noch einen verbindlich gesetzten Auftrag nach Stockwerk 0 im nächsten Plan. Zu beachten ist, daß Kabine 1 und 3 den vorgemerkten Auftrag, den Kabine 2 momentan abarbeitet, ebenfalls in ihren Plänen haben; Kabine 1 hat diesen Auftrag im nächsten Plan, Kabine 3 hat ihn in ihrem aktuellen Plan. Time=2: Kabinenzustand wie auf der linken Seite dargestellt. Kabine 3 ist in ihrem Zielstockwerk angekommen und hält an. Keine Änderung in den Plänen. Time=3: Kabine 1 ist in ihrem Zielstockwerk 0 angekommen und erhält einen Innenauftrag nach Stockwerk 5 (angedeutet durch abgerundetetes Rechteck mit Beschriftung 5). Kabine 3 befindet sich auf Stockwerk 4, setzt sich in Aufwärtsrichtung in Bewegung nach Stockwerk 5 (vorgemerkt gesetzter Auftrag). Kabine 2 und 3 arbeiten somit (kurzzeitig) am selben Auftrag. Der eingegangene Innenauftrag von Kabine 1 wird im nächsten Plan vermerkt, der Auftrag war schon vorgemerkt, wird nun allerdings verbindlich gesetzt, da er unbedingt von Kabine 1 abgearbeitet werden muß (siehe zur Plan-Auswahl bei Innenauftrag: Abb.3-4). Der erledigte Auftrag von Kabine 3 (verbindlich auf Stockwerk 4) wird gelöscht. Time=4: Kabine 1 setzt sich in Bewegung. Kabine 2 hat erkannt, daß Kabine 3 den Auftrag optimaler bearbeiten kann, da diese näher an Stockwerk 5 ist, und hält auf Stockwerk 3 an. Kabine 3 hat das Zielstockwerk 5 erreicht und hält an. Kabine 2 löscht ihren vorgemerkten Auftrag. Der erledigte Auftrag von Kabine 1 wird ebenfalls gelöscht. Planwechsel bei Kabine 1. Time=5: Kabinenzustand wie auf der linken Seite dargestellt. Der erledigte vorgemerkte Auftrag von Kabine 3 (vorgemerkt auf Stockwerk 5) wird für alle Kabinen gelöscht (in diesem Fall ist der Auftrag allerdings nur noch bei Kabine, vorgemerkt gesetzt). Planwechsel bei Kabine 3. Time=6: Kabinenzustand wie auf der linken Seite dargestellt. Keine Änderung der Pläne. Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 32 Time=7: Kabinenzustand wie auf der linken Seite dargestellt. Von Stockwerk 6 kommt ein AbwärtsAuftrag (abgerundetes Rechteck mit Beschriftung „Abwärts“). Der Außenauftrag wird für alle Kabinen vorgemerkt. Kabine 1 und 2 erhalten einen Eintrag im nächsten Plan. Kabine 3 kann den Auftrag erst im übernächsten Plan berücksichtigen (siehe zur Plan-Auswahl bei Außenauftrag: Abb.3-5). Time=8: Kabinenzustand wie auf der linken Seite dargestellt. Kabine 2 setzt sich auch in Bewegung, um den zur Zeit 7 eingetroffenen Auftrag in Angriff zu nehmen. Planwechsel bei Kabine 2, der aktuelle Plan von Kabine 2 enthält somit wieder einen Auftrag. Time=9: Kabine 1 hat das Zielstockwerk 5 erreicht und hält an. Ein neuer Außenauftrag von Stockwerk 2 wird erteilt. Der neue Außenauftrag wird in die Pläne der Kabinen eingetragen (siehe zur Plan-Auswahl bei Außenauftrag: Abb.3-5). Time=10: Kabine 1 möchte sich in Bewegung setzen, um den selben Auftrag wie Kabine 2 zu erledigen. Kabine 3 ist zwischenzeitlich am Zielstockwerk 0 angekommen. Der erledigte Auftrag von Kabine 1 wird gelöscht. Planwechsel bei Kabine 1. Time=11: Kabine 1 erkennt, daß Kabine 2 schon den Auftrag nach Stockwerk 6 erledigt und nimmt stattdessen den Auftrag nach Stockwerk 2 in Angriff. Kabine 1 und Kabine 3 arbeiten somit (kurzzeitig) am selben Auftrag. Kabine 1 löscht den vorgemerkten Auftrag für Stockwerk 6. Der erledigte Auftrag von Kabine 3 wird gelöscht. Planwechsel bei Kabine 1 und Kabine 3. Time=12: Kabine 1 erkennt, daß Kabine 3 den Auftrag besser erledigen kann, löscht ihren aktuellen Auftrag und fährt nicht an. Kabine 2 hat den vorgemerkten Auftrag abgearbeitet und teilt es allen Kabinen mit. Kabine 2 fährt in Richtung Stockwerk 2. Kabine 2 und 3 arbeiten am selben Auftrag. (Doch Kabine 3 ist näher am Ziel und wird daher im nächsten Schritt gewinnen.) Löschen des erledigten vorgemerkten Auftrags bei Kabine 2 und 3. Planwechsel bei Kabine 2. Auftreten von „Broadcast“ im Beispiel: Eine Mitteilung an alle Kabinen findet immer dann statt, wenn ein vorgemerkter Auftrag von einer Kabine abgearbeitet wurde (im Beipiel: Erledigung eines Auftrags zum Zeitpunkt 4 und 11, führt zum Löschen des Auftrags zum Zeitpunkt 5 und 12) oder ein neuer Außenauftrag eingetroffen ist (im Beipiel: Zum Zeitpunkt 7 und 9). Bewertung und Analyse der Spezifikationssprache DisCo 0 1 2 3 4 5 6 Time=1 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 vorgemerkt Je 3 Pläne pro Kabine: zu Kabine 1 verbindlich vorgemerkt vorgemerkt verbindlich verbindlich 0 1 2 3 4 5 6 zu Kabine 1 Time=2 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt verbindlich 3 Kabinen: verbindlich vorgemerkt verbindlich 3 Kabinen: aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster aktueller vorgemerkt nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 33 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 0 1 2 3 4 5 6 5 Kabine 1 Kabine 2 Kabine 3 Time=3 verbindlich zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: zu Kabine 1 verbindlich vorgemerkt vorgemerkt verbindlich 3 Kabinen: aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 0 1 2 3 4 5 6 zu Kabine 1 Time=4 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt verbindlich 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 34 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 0 1 2 3 4 5 6 Time=5 Kabine 1 Kabine 2 Kabine 3 zu Kabine 1 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: verbindlich 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 0 1 2 3 4 5 6 zu Kabine 1 Time=6 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: verbindlich 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 35 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 0 1 2 3 4 5 6 ABWÄRTS Time=7 Kabine 1 Kabine 2 Kabine 3 zu Kabine 1 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt verbindlich vorgemerkt 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 0 1 2 3 4 5 6 zu Kabine 1 Time=8 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt verbindlich vorgemerkt 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 36 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 0 1 2 3 4 5 6 Time=9 AUFWÄRTS Kabine 1 Kabine 2 Kabine 3 zu Kabine 1 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt vorgemerkt vorgemerkt verbindlich vorgemerkt 3 Kabinen: verbindlich aktueller nächster übernächster aktueller nächster übernächster aktueller nächster vorgemerkt übernächster 0 1 2 3 4 5 6 zu Kabine 1 Time=10 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt vorgemerkt verbindlich vorgemerkt 3 Kabinen: vorgemerkt aktueller nächster übernächster aktueller nächster übernächster aktueller nächster vorgemerkt übernächster 37 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 0 1 2 3 4 5 6 Time=11 Kabine 1 Kabine 2 Kabine 3 zu Kabine 1 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt vorgemerkt 3 Kabinen: vorgemerkt aktueller nächster übernächster aktueller nächster übernächster aktueller vorgemerkt nächster übernächster 0 1 2 3 4 5 6 zu Kabine 1 Time=12 Kabine 1 Kabine 2 Kabine 3 zu Kabine 2 zu Kabine 3 Je 3 Pläne pro Kabine: vorgemerkt vorgemerkt 3 Kabinen: aktueller nächster übernächster aktueller nächster übernächster aktueller nächster übernächster 38 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 39 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 3.4 Spezifikation und Implementierung Bei der Formulierung der Anforderungen wurde vielleicht schon deutlich, daß ein Denken in „Objekten“ und „Aktionen“ stattgefunden hat. Es soll in diesem Abschnitt keine nochmalige Trennung von natürlichsprachlicher und formaler Spezifikation vorgenommen werden. Vielmehr findet hier eine direkte Umsetzung in DisCo-Syntax statt. Grundsätzlich umfaßt diese Spezifikation die Festlegung passiver Datenstrukturen (Klassen) und aktiver, operationaler Strukturen (Aktionen). Die Klassendefinitionen werden durch Graphiken, die an Statecharts angelehnt sind (s. Bsp. Abb.2-6 (S.10)), veranschaulicht. Die Aktionsdefinitionen werden als Quelltexte gebracht, wie sie sich nachher auch im Programm wiederfinden. Auf eine vollständige Angabe des Programms, wie es der Ausführung zugrundelag, wird verzichtet1. 3.4.1 Klassen und Objekte Wie aus der Analyse hervorgeht, setzt sich das Aufzugsystem aus vielen Bestandteilen zusammen. Diese Komponenten werden als Klassen definiert und besitzen bestimmte Eigenschaften, die durch die Angabe von Zuständen , konstanten und variablen Parametern, sowie Referenzen auf andere Komponenten umfassend beschrieben werden können. Wie schon durch Abb.3-1 (S.21) zum Ausdruck kommt, kann das Gesamtsystem in drei funktionale Einheiten unterteilt werden, diese Unterteilung soll hier aufgegriffen werden. Den einzelnen Klassendefinitionen folgen kleine Abschnitte, zur Klärung der Bedeutung und der dahinterstehenden Idee. Außerdem sind dort Angaben zur Zahl der instanziierten Objekte und ihrer Initialisierungszustände im creation-part zu finden. Zum allgemeinen Aufbau einer Klasse in DisCo, siehe Kap.2.2.2.; zum Aufbau des creation-parts, siehe Kap.2.2.1. Aufgabenteil und Interaktionsteil Zum Aufgaben- und Interaktionsteil gehören zunächst Objekte vom Typ AUFZUGSSCHACHT, diese Klasse besteht aus nichts weiter als einem Bezeichner: Abbildung 3-6: Klasse AUFZUGSSCHACHT AUFZUGSSCHACHT Objekte von Typ Aufzugsschacht haben nur die Funktion, ein eindeutige Zuordnung der Objekte vom Kabinentyp zu treffen. Damit ist neben der Anzahl der Stockwerke, die Anzahl der Aufzugsschacht-Objekte ein weiterer variabler Parameter bei der Instanziierung des Aufzugsystems, er bestimmt eben, wieviele Aufzugsschächte, und damit, wieviele Kabinen im Gebäude vorhanden sein sollen. Als nächstes der KABINE-Typ. Ein Kabinen-Objekt hat einen konstanten Parameter A vom Typ AUFZUGSSCHACHT. Ein Kabinen-Objekt besitzt die Zustände AUFWÄRTS, 1.Bei Interesse am gesamten Quelltext, stellt ihn der Autor gerne zur Verfügung. Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 40 ABWÄRTS, die parallel sind zu den Zuständen EINGERASTET, NICHT EINGERASTET, BESCHLEUNIGEND, FAHREND, ABBREMSEND. Außerdem besitzt ein KabinenObjekt noch einen variablen Parameter STANDORT:integer: Abbildung 3-7: Klasse KABINE KABINE(A:AUFZUGSSCHACHT) EINGERASTET AUFWÄRTS NICHT EINGERASTET BESCHLEUNIGEND ABWÄRTS FAHREND ABBREMSEND STANDORT:integer Objekte von Typ KABINE bezeichnen den Zustand einer Kabine. Jede Kabine ist eindeutig einem Aufzugsschacht zugeordnet, daher der konstante Parameter vom Typ Aufzugsschacht. Der Zustand einer Kabine wird festgelegt durch die Bewegungsrichtung und die Bewegungsart, das kommt durch die parallele Anordnung der oben aufgeführten Zustände zum Ausdruck. Außerdem gibt ein ganzzahliger Parameter an, auf welchem Stockwerk sich eine Kabine momentan befindet. Die Anzahl der instanziierten Kabinen-Objekte ist gleich der Anzahl der Aufzugsschacht-Objekte, also im Prinzip variabel. Am Anfang befindet sich jede Kabine im untersten Stockwerk 0, ist eingerastet und die Bewegungsrichtung ist aufwärts. Weitere Aufgaben- und Interaktionsobjekte sind verschiedene Knöpfe: Richtungswahlknöpfe, Stockwerkswahlknöpfe, Notknöpfe, Türöffnen- und Türschliessenknöpfe. Sowie die drei Arten von Sensoren: Lichtschranke, Gewichtssensor und Rauchsensor. Es folgen zwei Beispiele für Klassendefinitionen. STOCKWERKKNOPF_INNEN-Objekte besitzen konstante Parameter K:KABINE und STOCKWERK_NR:integer. Weiter die Zustände NICHT AKTIVIERT, AKTIVIERT, die parallel sind zu den Zuständen LEUCHTET und LEUCHTET NICHT: Abbildung 3-8: Klasse STOCKWERKKNOPF_INNEN STOCKWERKKNOPF_INNEN(K:KABINE; STOCKWERK_NR:integer) NICHT AKTIVIERT LEUCHTET AKTIVIERT LEUCHTET NICHT Bewertung und Analyse der Spezifikationssprache DisCo 41 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Objekte von Typ STOCKWERKKNOPF_INNEN bezeichnen den Zustand eines Knopfes, der in der Kabine der Wahl eines Stockwerkes dient. Jeder Knopf leuchtet nachdem er gedrückt wurde auf und ist dann aktiviert bis zur Auftragserledigung. Jeder Stockwerksknopf wird mit einer Stockwerksnummer identifiziert, welches das Zielstockwerk ist. Jeder Stockwerksknopf gehört außerdem zu einem Kabinen-Objekt. Eine Kabine besitzt genau soviel Stockwerksknöpfe, wie es Stockwerke gibt. Also ist die Anzahl der im creation-part zu instanziierenden Stockwerksknopf-Objekte gleich (Anzahl Stockwerke)*(Anzahl Aufzugsschächte). Zu Anfang ist der Stockwerksknopf nicht gedrückt und leuchtet daher nicht auf. RICHTUNGSKNOPF_AUSSEN besitzt die konstanten Parameter STOCKWERK_NR: integer und AUFWAERTS:boolean. Weiter die Zustände NICHT AKTIVIERT, AKTIVIERT, die parallel sind zu den Zuständen LEUCHTET und LEUCHTET NICHT: Abbildung 3-9: Klasse RICHTUNGSKNOPF_AUSSEN RICHTUNGSKNOPF_AUSSEN(STOCKWERK_NR:integer;AUFWAERTS:boolean) NICHT_AKTIVIERT LEUCHTET AKTIVIERT LEUCHTET NICHT Objekte vom Typ RICHTUNGSKNOPF_AUSSEN bezeichnen den Zustand eines Knopfes, der auf einem Stockwerk die Anforderung einer Kabine in eine bestimmte Fahrtrichtung ermöglichen soll. Jeder Knopf leuchtet bei Betätigung auf und ist dann aktiviert bis eine Kabine mit der richtigen Fahrtrichtung auf diesem Stockwerk die Türen öffnet. Jeder Richtungsknopf wird mit der Stockwerksnummer identifiziert, die angibt, auf welchem Stockwerk sich dieser Knopf befindet. Jeder Richtungsknopf zeigt entweder aufwärts oder abwärts, was durch den booleschen Wertebereich von AUFWAERTS zum Ausdruck kommt. Auf jedem Stockwerk befinden sich genau zwei Richtungsknöpfe, Ausnahmen sind oberstes und unterstes Stockwerk, dort ist nur ein Richtungsknopf nach unten (bzw. nach oben) vorhanden. Also ist die Anzahl der im creation-part zu instanziierenden Richtungsknopf-Objekte gleich 2*(Anzahl Stockwerke)-2. Zu Anfang ist kein Richtungsknopf gedrückt und keiner leuchtet. Alle anderen Klassen (Lichtschranke, Türöffnenknopf, Türschliessenknopf, Notknopf, Rauchsensor, Gewichtsensor, Stockwerksanzeige innen, Richtungsanzeige außen), die dem Aufgaben-/Interaktionsteil zugerechnet werden können, sind ähnlich trivial; sie besitzen im wesentlichen zwei Zustände, aktiviert und nicht aktiviert, die Knöpfe können zusätzlich bei Aktivierung leuchten. Auf die Darstellung dieser Klassen wird daher verzichtet. Steuerungsteil Zur Steuerung gehören alle Objekte, die der Verwaltung der Aufträge und der Fahrtsteuerung der Kabinen dienen. Natürlich sind von Steuerungsaufgaben generell alle Objekte betroffen, aber als ausschließliche „Buchhaltungsobjekte“ können die Klassen „Plan“, „Auftrag“, sowie insbesondere „Event“ bezeichnet werden. Zunächst zum Zusammenhang von „Kabine“„Plan“-„Auftrag“. Bewertung und Analyse der Spezifikationssprache DisCo 42 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Zwischen den Objekten der Klassen „Kabine“-„Plan“-„Auftrag“ besteht eine Referenzbeziehung, wie in Abb.3-10 skizziert. Jede Kabine besitzt drei Pläne entsprechend der Anforderungsanalyse. Die Anzahl der Kabinen ist gleich der Anzahl der Aufzugsschächte. Jeder Plan „besitzt“ ein Ensemble aller möglichen Aufträge, das sind soviele, wie es Stockwerke gibt. Die Bindung der Objekte aneinander wird durch konstante Parameter in den Klassendefinitionen bewerkstelligt. Alle konstanten Objektreferenzen werden selbstverständlich zum Zeitpunkt der Instanziierung festgelegt, dies geschieht bekanntlich im creation-part der DisCo-Spezifikation, und bleiben dann über die gesamte Laufzeit des Programms erhalten. Somit ergibt sich die Anzahl der Plan-Objekte als 3*(Anzahl der Aufzugsschächte) und die Anzahl der AuftragsObjekte als 3*(Anzahl der Aufzugsschächte)*(Anzahl der Stockwerke). Abbildung 3-10: Referenzen zwischen Klasse-Plan-Auftrag ... AUFTRAG3_3 AUFTRAG1_1 AUFTRAG3_2 PLAN1 PLAN3 AUFTRAG1_2 AUFTRAG3_1 AUFTRAG1_3 ... KABINE1 ... PLAN2 AUFTRAG2_1 AUFTRAG2_3 AUFTRAG2_2 „konstante Referenz auf“ Das PLAN-Objekt besitzt zunächst eine Referenz zu einer Kabine - K:KABINE, dann die Zustände AUFWÄRTS, ABWÄRTS, die parallel zu den Zuständen AKTUELLER, NÄCHSTER, ÜBERNÄCHSTER sind. Zustand AKTUELLER enthält als lokalen, veränderlichen Parameter noch HALT:integer: Abbildung 3-11: Klasse PLAN PLAN(K:KABINE) AKTUELLER AUFWÄRTS HALT:integer NÄCHSTER ABWÄRTS ÜBERNÄCHSTER Bewertung und Analyse der Spezifikationssprache DisCo 43 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Jedes Plan-Objekt gehört zu genau einem Kabinen-Objekt. Ist ein Plan im Zustand aktuell, enthält das Plan-Objekt noch Information über das nächste Haltestockwerk in Form eines ganzzahligen Parameters, hierdurch wird wichtige Information lokal gehalten und muß nicht erst umständlich gesucht werden. Jede Kabine besitzt genau drei Pläne. Der Grund hierfür liegt in einer einfacheren Buchhaltung eingehender Aufträge. Es muß darauf geachtet werden, daß ein Kabinenplan im Zustand „aktuell“, einer im Zustand „nächster“ und einer im Zustand „übernächster“ ist. Im Laufe der Zeit ändert sich dieses Attribut eines einzelnen Planes natürlich, da ein Plan immer weiter nach „vorne aufrückt“, bis er „aktuell“ wird. Wenn ein Plan vollständig abgearbeitet ist, wird er im allgemeinen auch das Attribut der Abarbeitungsrichtung ändern, was durch einen Wechsel der beiden sequentiellen Zustände „aufwärts“ und „abwärts“ möglich ist. Zu Anfang ist ein Plan pro Kabine im Zustand „aktueller“, der „Halt“-Parameter ist dann 0 (unterstes Stockwerk), die Plan-Richtung ist „aufwärts“. Der zweite Plan pro Kabine befindet sich im Zustand „nächster“ und „abwärts“ und der dritte Plan pro Kabine befindet sich im Zustand „übernächster“ und „aufwärts“. Das AUFTRAG-Objekt besitzt eine Referenz zu einem Plan - P:PLAN und einen konstanten Parameter STOCKWERK:integer, dann die Zustände NICHT GESETZT, VORGEMERKT, VERBINDLICH, GESTEUERT. Abbildung 3-12: Klasse AUFTRAG AUFTRAG(P:PLAN, STOCKWERK:integer) NICHT GESETZT VORGEMERKT VERBINDLICH GESTEUERT Für jeden Plan existiert jeweils eine vollständige Menge aller möglichen Aufträge, die sich durch die Angabe des Haltestockwerks voneinander unterscheiden. Diese Aufträge können nun gesetzt sein, vorgemerkt sein, verbindlich sein oder aber für Sonderfälle (z.B. Notsituationen), gesteuert sein. Am Anfang sind alle Aufträge „nicht gesetzt“. Besondere Bedeutung besitzt die Klasse EVENT. Hiervon existiert nur eine Objektinstanz, welche als eine Art globale Variable angesehen werden kann, deren Zustand in allen Aktionsbedingungsteilen abgefragt wird. Zunächst zur Definition der Klasse, wegen des Umfangs hier nicht graphisch, sondern in DisCo-Formulierung: Listing 3-1: class EVENT is state *NIL, NAECHSTER_AUFTRAG, INNENAUFTRAG_SETZEN, AUSSENAUFTRAG_SETZEN, AUSSENAUFTRAG_LOESCHEN, INNENAUFTRAG_LOESCHEN, OPTIMIEREN, KABINEN_BETEILIGEN, KABINE_STEUERN, TUER_OEFFNEN, TUER_SCHLIESSEN; Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 44 extend NAECHSTER_AUFTRAG by state *ALLE_KABINEN, EINE_KABINE; end; extend KABINEN_BETEILIGEN by state *WEGEN_AUSSENAUFTRAGLOESCHEN, WEGEN_AUSSENAUFTRAGSETZEN, WEGEN_NAECHSTERAUFTRAG, WEGEN_STEUERN; end; end EVENT; Während des Programmablaufs können die verschiedensten Ereignisse eintreten, die es erforderlich machen, die nichtdeterministische Auswahl der Aktionen und Objekte, durch zusätzliche Kontrollfluß-Mechanismen einzuschränken. Hierzu wird die Event-Klasse, bzw. das Event-Objekt benötigt. Mit Hilfe des Event-Objekts wird eine Sequentialisierung des Programmablaufs erzwungen. Das Event-Objekt dient zur Bekanntmachung von eingetretenen Ereignissen, indem jedem Ereigniss ein Event-Zustand zugeordnet wurde. Da das EventObjekt in allen Aktionen abgefragt wird, weiß jede Aktion, welche Ereignisse eingetreten sind. Manche Aktionen sind nun durch einen bestimmten Zustand des Event-Objekts gesperrt, andere Aktionen hingegen werden hierdurch erst ermöglicht. Insofern kann das Event-Objekt als eine Art Statusregister angesehen werden, das Information über die Event-auslösende Aktion und deren nähere Klassifizierung enthält. Die Idee ist nun, daß bei Eintreten von Aktionen, die das Umsetzen des Event-Objekts bewirken, also ein Übergang aus dem Zustand NIL in einen anderen Ausnahme-Zustand (z.B. AUSSENAUFTRAG_SETZEN), alle Aktionen gesperrt werden, die aufgrund des momentanen Systemzustands nicht ausgeführt werden dürfen. Beispiel ist das Drücken eines Richtungsknopfes; hiernach müssen erst alle Kabinen über den neu eingetroffenen Auftrag unterrichtet werden, um ihren momentanen Bewegungsablauf auf optimale Auftragserledigung zu überprüfen. Bei obiger EVENT-Klassendefinition wurde nun so vorgegangen, daß einfach eine Auflistung aller möglichen Ereignisse, die zusätzliche Kontrollflußsteuerung notwendig machen, durchgeführt wurde. Jedem Ereignis wurde genau ein Eventzustand zugeteilt. Manche Ereignisse erfordern eine zusätzliche nähere Beschreibung, so kann im Zustand KABINEN_BETEILIGEN, Information über den Grund einer Kabinenbeteiligung (WEGEN_AUSSENAUFTRAGLOESCHEN, WEGEN_AUSSENAUFTRAGSETZEN, WEGEN_NAECHSTERAUFTRAG, WEGEN_STEUERN) im EVENT-Objekt mitgegeben werden. Nun wurde so verfahren, daß jedem Ausnahme-Zustand des EVENT-Objekts genau eine mögliche weitergehende Aktionsausführung entspricht. Das heißt, tritt eine Aktion ein, die zu einem Event führt, ist der Programmablauf deterministisch festgelegt, denn nur die zum Eventzustand gehörige Aktion darf unmittelbar folgen, alle anderen Aktionen werden durch die Angabe entsprechender Aktionsbedingungen gesperrt (Folge: Sequentialisierung). Allerdings muß beachtet werden, daß ja nicht nur die Aktionen nichtdeterministisch ausgewählt werden, sondern auch die Teilnehmer-Objekte. Deshalb ist es notwendig, auch die Objekte, die an der EventAktion beteiligt sein dürfen, zu kennzeichnen. Wie dies geschieht, wird im folgenden erläutert. Noch anzumerken bleibt, daß das eine EVENT-Objekt zu Anfang den Zustand NIL einnimmt. Zur Anwendung des Event-Objekts siehe auch Kap.3.4.3. Erweiterung der Klassen zur Eventbehandlung Die Klassen, wobei hier alle Klassen, außer der Klasse „Event“ gemeint sind, müssen zur Bewertung und Analyse der Spezifikationssprache DisCo 45 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Unterstützung des Eventmechanismus, wie oben erläutert, um zusätzliche Angaben erweitert werden. Hierzu dient ein einfacher Extension-Schritt im DisCo-Sinne (s. Kap.2.2.2). Die Idee ist, daß jedes Objekt einen zusätzlichen variablen Parameter BETEILIGT vom booleschen Typ erhält, der angibt, ob ein Objekt an der Event-Aktion teilnehmen darf oder nicht. Zum Beispiel bei der Klasse KABINE - ausgehend von obiger Klassendefinition in Abb.3-7 - kann folgende Extension durchgeführt werden. Der veränderlichen Parameter BETEILIGT wird am Anfang auf false gesetzt: Listing 3-2: extend KABINE(...) by BETEILIGT:boolean := false; ... end KABINE; An welcher Folge-Aktion das Objekt teilnehmen darf, wird durch den Zustand des EventObjekts spezifiziert. Beispiel hierfür sei das Drücken eines Richtungsknopfes außen. Nach dem Schalten der Aktion KNOPFDRUCK_AUSSEN folgt eine Art 3-Phasen-Protokoll, in der ersten Phase muß dafür gesorgt werden, daß alle Kabinen-Objekte ihren Parameter BETEILIGT auf TRUE setzen, hiernach sind sie alle berechtigt an einer Event-Aktion, die durch den Zustand des Statusregisters festgelegt wird, teilzunehmen. In der zweiten Phasen findet die eigentliche „Versorgung“ aller Kabinen mit der neuen Information statt (in diesem Falle besteht die Information in der Angabe von Stockwerksnummer und Richtung), was also in diesem Fall bedeuten würde, daß der entsprechende Auftrag vorgemerkt gesetzt wird. Konkret wird der Zustand des Auftrag-Objekts mit entsprechendem STOCKWERK:integer-Parameter, das einen Plan mit entsprechendem Richtungsattribut referenziert (Parameter P:PLAN) auf VERBINDLICH gesetzt. In der dritten Phase wird für alle Kabinen-Objekte der Parameter BETEILIGT auf FALSE gesetzt und das Statusregister geht in den Normalzustand NIL über, der Vorgang ist damit erledigt - alle Kabinen befinden sich auf dem „neuesten Informationsstand“. Diese Darstellung des Broadcast-Protokolls war etwas vereinfacht, der eigentliche Ablauf wird im folgenden noch genauer gebracht. 3.4.2 Aktionen Wie schon in der Beschreibung der Klassendefinitionen, kann auch bei den Aktionen zwischen typischen Steuerungsaktionen und typischen Kabinenaktionen bzw. Benutzerinteraktionen unterschieden werden. Wobei diese Unterscheidung hier eher auf der natürlichen Anschauung gründet, als auf der Struktur (z.B. der Art der Teilnehmerobjekte) der Aktionen. Hier soll es zunächst um einzelne, beispielhafte Aktionen gehen. Einen Überblick über das Zusammenspiel, d.h. den Ablauf mehrer Aktionen (Aktivitäten), bietet der nächste Abschnitt anhand eines Fallbeispiels. Zum Aufbau einer Aktion in DisCo siehe Kap.2.2.3. Allen Aktionen des Aufzugszenarios gemeinsam, ist die Beteiligung des einen Event-Objekts, es trägt immer den selben Teilnehmernamen EV. EV wird im Aktionsbedingungsteil auf seinen momentanen Zustand abgefragt; alle Kabinenaktions- und Interaktionsausführungen setzen voraus, daß sich EV im Zustand NIL befindet, alle Event-Aktionen (Steueraktionen) sind nur aktivierbar, wenn sich Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 46 EV in einem ausgezeichneten (von NIL unterschiedenen) Zustand befindet, der zu dieser Event-Aktion gehört. Aufgabenteil und Interaktionsteil Die Aufgaben einer Kabine sind: Anfrage, Kabine_entsichern, Beschleunigen, Fahren, Bremsen, Halten, Kabine_sichern, Tuer_oeffnen, Tuer_schliessen, Kabine_entsichern. Die Interaktionen, die der Benutzer tätigen kann, werden festgelegt durch: Knopfdruck_innen, Knopfdruck_aussen, Notknopf_druecken etc. Ein Beispiel für eine Kabinen-Aktion ist die Aktion BESCHLEUNIGEN, sie besitzt folgende Teilnehmer: K:KABINE, P:PLAN, A:AUFTRAG, EV:EVENT. Listing 3-3: action BESCHLEUNIGEN by K:KABINE; P:PLAN; A:AUFTRAG; EV:EVENT is when EV.NIL and (K.NICHT_EINGERASTET or K.ABBREMSEND) and K=P.K and P.AKTUELL and A.P=P and A.STOCKWERK_NR=P.AKTUELL.STOCKWERK_NR and not(A.NICHT_GESETZT) and K.STOCKWERK_NR/=A.STOCKWERK_NR do if(K.STOCKWERK_NR < A.STOCKWERK_NR) then ->K.AUFWAERTS; else ->K.ABWAERTS; end if; ->K.BESCHLEUNIGEND; if(A.VORGEMERKT_GESETZT) then ->EV.OPTIMIEREN; A.BETEILIGT:=true; end if; end; Die Aktion in Listing 3-3 repräsentiert das Beschleunigen einer Kabine nach einem Kabinenstop oder nach einer Abbremsephase. Die Kabine muß sich also in dem nicht gesicherten Zustand befinden oder im Bremsvorgang (entspricht Bedingung: K.NICHT_EINGERASTET or K.ABBREMSEND). Der Beschleunigungsvorgang muß in die richtige Richtung stattfinden, daher müssen aktueller Plan und aktueller Auftrag gecheckt werden, die zu dieser Kabine gehören, und es muß natürlich überhaupt ein gesetzter Auftrag vorliegen, denn sonst soll die Kabine nicht anfahren (entspricht Bedingung: K=P.K and P.AKTUELL and A.P=P and A.STOCKWERK_NR=P.AKTUELL.STOCKWERK_NR and not(A.NICHT_GESETZT)). Befindet sich die Kabine auf demselben Stockwerk, zu dem sie fahren muß, so darf sie ebenfalls nicht anfahren (entspricht Bedingung: K.STOCKWERK_NR/=A.STOCKWERK_NR). Falls die Aktionsbedingungen für irgendwelche Objekte erfüllt sind, wird mit der Aktionsausführung begonnen. Dort wird geprüft, ob sich die Kabine über oder unterhalb des Auftragsstockwerks befindet, um sie dann in die richtige Richtung zu beschleunigen (angezeigt durch: if(K.STOCKWERK_NR < A.STOCKWERK_NR) then ...). Dann geschieht die Beschleunigung (angezeigt durch: ->K.BESCHLEUNIGEND). Falls es sich bei dem aktuellen Auftrag Bewertung und Analyse der Spezifikationssprache DisCo 47 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ um einen vorgemerkten Auftrag handelt, muß ein Optimierungsschritt eingeleitet werden, dessen Aufgabe darin besteht, die Auftragsabarbeitung mit allen anderen Kabinen zu koordinieren und eine Entscheidung darüber herbeizuführen, ob der Auftrag tatsächlich weiterhin von dieser Kabine abgearbeitet werden soll. Dieser Optimierungsschritt wird als Event-Aktion realisiert (angezeigt durch: ->EV.OPTIMIEREN). Es muß außerdem eine Kennzeichnung des Auftrags, um den es geht, durchgeführt werden (angezeigt durch: A.BETEILIGT:=true). Die EventAktion, die zu diesem Event gehört heißt EV_Optimieren. Ein Beispiel für eine Benutzer-Aktion: die Aktion KNOPFDRUCK_INNEN in Listing 3-4 besitzt folgende Teilnehmer: K:KABINE, SK_I:STOCKWERKKNOPF_INNEN, KT:KABINEN_TUER, S_T :STOCKWERK_TUER, EV:EVENT. Listing 3-4: action KNOPFDRUCK_INNEN by K:KABINE; SK_I:STOCKWERKKNOPF_INNEN; KT:KABINEN_TUER; S_T:STOCKWERK_TUER; EV:EVENT is when EV.NIL and K=SK_I.K and S_T.K=K and S_T.STOCKWERK_NR=K.STOCKWERK_NR and KT.K=K and S_T.ZU and KT.ZU do if SK_I.NICHT_AKTIVIERT then ->EV.INNENAUFTRAG_SETZEN; ->SK_I.AKTIVIERT; ->SK_I.LEUCHTET; SK_I.BETEILIGT:=true; K.BETEILIGT:=true; end if; end; Diese Aktionsausführung repräsentiert die Stockwerkswahl in einer Kabine. Der Fahrgast kann ein Stockwerk auswählen und den entsprechenden Stockwerksknopf drücken. Die Aktion kann nur ausgeführt werden, falls die Türen geschlossen sind (entspricht Bedingung: S_T.ZU, KT.ZU), was eher zur Vereinfachung der Spezifikation dient, als durch die Anschauung begründet ist! Zum Event-Status siehe Bemerkungen oben. Alle anderen Aktionsbedingungen sorgen dafür, daß die zueinandergehörigen Komponenten ausgewählt werden, es soll schließlich nicht ein Knopf einer Kabine A gedrückt werden können, wenn sich der Fahrgast in der Kabine B befindet (entspricht Bedingung: K=SK_I.K)! Ebenso verhält es sich mit den Kabinen- und Stockwerktüren (entspricht Bedingung: KT.K=K, S_T.K=K, S_T.STOCKWERK_NR =K.STOCKWERK_NR). Falls die Aktionsbedingungen für irgendwelche Objekte erfüllt sind, wird mit der Aktionsausführung begonnen. Dort wird geprüft, ob der Knopf innen nicht schon zuvor gedrückt wurde, was zu keiner weiteren Zustandsänderung der Objekte führen soll. Ansonsten werden alle nötigen Zustandsübergänge ausgeführt. Wie zu sehen ist, führt das Drücken eines Stockwerkknopfes zu einem Event (angezeigt durch: -> EV.INNENAUFTRAG_SETZEN). Somit müssen die relevanten Objekte (K und SK_I) als teilnahmeberechtigt für die eindeutig nachfolgende Event-Aktion gekennzeichnet werden (angezeigt durch: SK_I.BETEILIGT:=true und K.BETEILIGT:=true). Die Event-Aktion, die zu diesem Event gehört heißt EV_InnenauftragSetzen. Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 48 Steuerungsteil In der Erläuterung der vorigen zwei Beispiel-Aktionen wurden die Event-Aktionen EV_Optimieren und EV_InnenauftragSetzen erwähnt, die erstere wird nun beschrieben. Es ist anzumerken, daß die Wahl der Bezeichner „EV_Optimieren“ und „EV_InnenauftragSetzen“ selbstverständlich willkürlich ist. In DisCo wird ExceptionHandling nicht unterstützt, es handelt sich hier um ein vom Programmierer gewähltes Konzept, das keinerlei syntaktische oder semantische Unterstützung durch die DisCo-Sprache erfährt. Es sollte hier aber zumindest eine lexikalische Unterscheidung der Event-Aktionen von allen übrigen Aktionen stattfinden. Bei allen anderen Steuerungsaktionen wurde gleich verfahren, d.h. jeder Eventzustandsmarke (s.Listing 3-1) wurde eindeutig eine Event-Aktion zugeordnet, nach dem Muster „EV_Name_Event_Zustand„ o.ä., die dann nach Eintreffen eines Event als einzig mögliche, nächste Aktion aktivierbar ist. Die Aktion EV_Optimieren besitzt folgende Teilnehmer K:KABINE, P:PLAN, A:AUFTRAG, EV:EVENT. Listing 3-5: action EV_Optimieren(K_SCHLECHTER:boolean) by K:KABINE; P:PLAN; A:AUFTRAG; EV:EVENT is when EV.OPTIMIEREN and A.BETEILIGT and P=A.P and K=P.K and K_SCHLECHTER=( or/ K2:KABINE | K2/=K :: or/ P2:PLAN | P2.K=K2 and P2.AKTUELL and ((P.ABWAERTS and P2.ABWAERTS) or (P.AUFWAERTS and P2.AUFWAERTS)) and A.STOCKWERK_NR=P2.AKTUELL.STOCKWERK_NR :: or/ A2:AUFTRAG | A2.P=P2 and A2.STOCKWERK_NR=P2.AKTUELL.STOCKWERK_NR and A2.VORGEMERKT_GESETZT :: abs(K.STOCKWERK_NR-P.AKTUELL.STOCKWERK_NR) >= abs(K2.STOCKWERK_NR-P2.AKTUELL.STOCKWERK_NR)) do if(K_SCHLECHTER) then ->A.NICHT_GESETZT; end if; A.BETEILIGT:=false; ->EV.NIL; end; Diese Aktionsausführung repräsentiert einen Optimierungsschritt, der den Zweck hat, zur Entscheidung zu führen, ob eine Kabine einen vorgemerkten Auftrag weiter abarbeiten oder stornieren soll. Die Entscheidung soll aufgrund von Optimierungskriterien getroffen werden. Die Aktion wird nach jedem Fahrtschritt einer Kabine, die momentan an einem vorgemerkten Auftrag arbeitet, ausgeführt. Unter „Fahrtschritt“ seien hier Aktionen wie Beschleunigen, Fahren, Bremsen, Halten gemeint. In diesen Aktionen wird EV auf EV.OPTIMIEREN gesetzt, was eine Voraussetzung für die Aktivierbarkeit von EV_Optimieren darstellt (siehe Bedingung: EV.OPTIMIEREN). Es ist anzumerken, daß durch die Eindeutigkeit des Eventzustands sichergestellt ist, daß keine andere Aktion aktivierbar ist. Zunächst muß ein Auftrag-Objekt anhand Bewertung und Analyse der Spezifikationssprache DisCo 49 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ seiner Berechtigung an der Event-Aktion teilzunehmen, gesucht werden, ebenso das zugehörige Plan-Objekt und Kabinen-Objekt (entspricht Bedingung: A.BETEILIGT and P=A.P and K=P.K). Ein variabler Parameter K_SCHLECHTER:boolean wird nun mit einem booleschen Ausdruck gleichgesetzt. Dieser Ausdruck wertet sich als true aus, falls es eine optimalere Kabine gibt und zu false, falls keine optimalere Kabine existiert, und K somit mit der Auftragsabarbeitung fortfahren soll. (entspricht Bedingung: K_SCHLECHTER= („boolescher_Ausdruck“)). Bei dem booleschen Ausdruck handelt es sich genauer um einen booleschen quantifizierten Ausdruck, mit dem Exist-Quantor or/ (siehe Anmerkungen in Kap.2.2.3). Durch den Ausdruck wurde folgende natürlichsprachliche Spezifikationsanforderung formalisiert: „Die Kabine K ist dann schlechter, wenn es eine andere Kabine K2 gibt (entspricht Bedingung: K2/=K), so daß es einen aktuellen Plan P2 in dieselbe Richtung gibt (entspricht Bedingung: P2.AKTUELL and ((P.ABWAERTS and P2.ABWAERTS) or (P.AUFWAERTS and P2.AUFWAERTS))), der zu dieser Kabine K2 gehört (entspricht Bedingung: P2.K=K2), so daß es einen vorgemerkten Auftrag A2 gibt, der zu diesem Plan P2 gehört (entspricht Bedingung: A2.P=P2), der dieselbe Stockwerksnummer wie P2.AKTUELL (was der aktuelle Auftrag von Kabine K2 ist) besitzt (entspricht Bedingung: A2.STOCKWERK_NR =P2.AKTUELL.STOCKWERK_NR), so daß schließlich K2 näher am Ziel ist als K (entspricht Bedingung: abs(...)>=abs(...)).“ Der Ausdruck abs(...) >= abs(...) berechnet den absoluten Abstand vom Zielstockwerk für beide Kabinen und vergleicht die beiden Werte miteinander. Wurde dieser Ausdruck ausgewertet, enthält K_SCHLECHTER die korrekte Belegung und kann somit im Aktionsausführungsteil herangezogen werden, um zur Entscheidung zu gelangen, ob K die Abarbeitung von A fortführen soll oder nicht (angezeigt durch: ->A.NICHT_GESETZT). Die Event-Aktion ist damit beendet (angezeigt durch: ->EV.NIL;) und A wird von „allen Pflichten befreit“ (angezeigt durch: A.BETEILIGT:=false;). 3.4.3 Komplexe Abläufe Wie in der Erläuterung einzelner Aktionen im vorigen Teil deutlich wurde, ergeben sich komplexere Abläufe im Systemverhalten durch ein Zusammenspiel verschiedener Aktionen. Komplexe Abläufe, die hier als Aktivitäten bezeichnet werden sollen, müssen daher durch Kontrollflußmechanismen, die über mehrere Aktionenausführungen hinweg wirksam sind, gesteuert werden. Da jede Art des Kontrollflusses innerhalb von DisCo-Programmen nur implizit durch die Formulierung der Aktionsbedingungen geschehen kann, wurde die oben erwähnte Datenstruktur „Event“ eingeführt, die prinzipiell nichts anderes als eine globale Variable darstellt. Das Event-Objekt wurde schon ausführlich dargestellt. Es soll hier nochmals anhand eines Beispiels gezeigt werden, wie eine Aktivität, nämlich Broadcast als Kommunikationsmechanismus, in diesem Programm mit Hilfe des Event-Objekts realisiert wurde. Realisierung von Broadcast am Beispiel „Neuer Außenauftrag“ Durch Drücken eines Knopfes auf einem Stockwerk, fordert eine Person eine Kabine an. Wie schon gesagt, kommen hierfür generell alle Kabinen in Betracht. Somit muß eine Rundmeldung durchgeführt werden, um die Information „Stockwerksnummer“ und „Richtungswahl“ Bewertung und Analyse der Spezifikationssprache DisCo 50 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ zunächst allen Kabinen mitzuteilen. Angestoßen wird diese Aktivität also durch die Aktion KNOPFDRUCK_AUSSEN, wie Abb.3-13 zeigt. An dieser Aktion sind Objekte Richtungsknopf und Event beteiligt. Der Richtungsknopf wird in KNOPFDRUCK_AUSSEN aktiviert, sein Beteiligt-Parameter auf true gesetzt und somit für die Teilnahme an einer Event-Aktion vorbereitet. Das Event-Objekt wird von NIL auf KABINENBETEILIGEN.WEGEN _AUSSENAUFTRAGSETZEN gesetzt. Abbildung 3-13: Beispiel einer Aktivität - „Broadcast nach Eingang eines Außenauftrags“ START KNOPFDRUCK_AUSSEN RICHTUNGSKNOPF_AUSSEN EVENT EV R_K Aktion KNOPFDRUCK_AUSSEN schalten: Setze EV auf KABINEN_BETEILIGEN.WEGEN_AUSSENAUFTRAGSETZEN und R_K auf AKTIVIERT und R_K.BETEILIGT:=true. EV_BeteiligeKabinen KABINE K EVENT EV Aktion EV_BeteiligeKabinen schalten: Setze K.BETEILIGT:=true falls noch Kabinen unbeteiligt falls alle Kabinen beteiligt EV_BeteiligeKabinenENDE KABINE K EVENT EV Aktion EV_BeteiligeKabinenENDE schalten: Setze EV auf AUSSENAUFTRAG_SETZEN. „In allen Kabinen Außenauftrag vormerken“ & „Broadcast beenden“ Bewertung und Analyse der Spezifikationssprache DisCo 51 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ Durch diesen Eventzustand ist dann als einzig mögliche nächste Aktion EV_BeteiligeKabinen ausführbar. Die Aufgabe dieser Aktion ist es, den BETEILIGT-Parameter aller Kabinen-Objekte auf true zu setzen. Das geschieht durch Abfrage im Aktionsbedingungsteil in der Art „sind noch Kabinenobjekte unbeteiligt?“, was sich auf einfache Weise mit dem Exist-Quantor bewerkstelligen läßt. Wenn noch ein Kabinen-Objekt unbeteiligt ist, wird ein solches ausgewählt und dessen BETEILIGT-Parameter auf true gesetzt. Sind keine Kabinen mehr unbeteiligt, so ist die Aktion EV_BeteiligeKabinen nicht mehr aktivierbar, sondern die „Abschluß-Aktion“ EV_BeteiligeKabinenENDE als einzig mögliche nächste Aktion. Das hat allein den Zweck, die vorherige Iteration zu beenden, indem dort das EventObjekt auf AUSSENAUFTRAG_SETZEN gesetzt wird. Daran anschließend wird eine weitere Iteration durchgeführt, in der die Bekanntgabe der Informationen an alle Kabinen geschieht („In allen Kabinen Außenauftrag vormerken“). Dieser Iteration folgt schließlich der Abschluß des Broadcast-Vorgangs durch Aktivierung einer weiteren Event-Aktion („Broadcast beenden“). 3.5 Ausführung der Spezifiktion Nach der Implementierung wurde ein erster Test der Spezifikation durchgeführt. Bei den ersten Programmausführungen wurden erwartungsgemäß Spezifikationsfehler sichtbar, einerseits durch das Eintreten von Deadlocks, andererseits durch offensichtlich falsches Systemverhalten. Bei Eintreten von Deadlocks war es relativ einfach, die Fehlerquellen ausfindig zu machen, die Gründe lagen zumeist in der falschen Formulierung von Aktionsbedingungen. Fehlerquelle war hier vorallem die falsche Anordnung der konjunktiv verknüpften Bedingungen innerhalb des booleschen Ausdrucks (die Auswertung des Ausdrucks geschieht durch den DisCo-Interpreter von links nach rechts, die Auswertung bricht ab, sobald sie eindeutig ist). Um Systemverhalten zu untersuchen, bedarf es normalerweise umfangreicher Tests, diese sind mit DisCo nicht möglich, wie in Kap.4 noch begründet wird. Daher konnte nicht verifiziert werden, ob komplexere Anforderungen (z.B. die „optimale“ Auftragsabarbeitung) durch die Spezifikation erfüllt wurden. Was die Techniken des Broadcast, der Kommunikation zwischen Kabinen und deren Koordination anbelangt, kann davon ausgegangen werden, daß zumindest konzeptionell eine akzeptable Spezifikation stattgefunden hat. Auch Zeitbetrachtungen wurden nur am Rande durchgeführt. Dies hat zwei Gründe, zum einen wurden keine Zeitrestriktionen bei der Anforderungsanalyse (im vorgegebenen Pflichtenheft) formuliert, zum anderen werden Zeitbetrachtungen, zum Beispiel die Verifikation vorgegebener Zeitrahmen, durch das DisCo-Tool nicht gut genug unterstützt (s. Kap.4). 3.6 Zusammenfassung In diesem Kapitel wurde versucht einen Eindruck zu vermitteln, wie die Spezifikation des Aufzugsystems unter DisCo realisiert wurde. Die wesentlichen Abschnitte bei der Implementierung lassen sich vereinfacht so zusammenfassen: Bewertung und Analyse der Spezifikationssprache DisCo 3 Beispiel einer Spezifikation in DisCo: „Aufzugssteuerung“ 52 1. Idee: Trennung in Interaktions-, Aufgaben-, und Steuerungsteil. 2. Definition der Aufgaben- und Interaktions-Klassen. 3. Idee: Steuerung von komplexen Aktivitäten durch „Event“ als globale Variable. 4. Definition der Steuerungsklassen. Anpassung der anderen Klassen an das Event-Konzept. 5. Idee: Broadcast-Mechanismus. 6. Definition aller Aktionen unter Berücksichtigung des Event-Konzepts. Verifikation durch Test, Simulation, Animation konnte auf Grund der langsamen Programmausführung nicht ausreichend durchgeführt werden. Dennoch erwiesen sich die gewählten Mechanismen („Event“, „Broadcast“) zur Steuerung von Aktivitäten grundsätzlich als akzeptabel. Bewertung und Analyse der Spezifikationssprache DisCo 53 4 4 Analyse von DisCo Analyse von DisCo Gegenstand der Evaluation des DisCo-Systems ist zum einen die DisCo-Programmiersprache und zum anderen das DisCo-Tool, d.h. die Benutzungsoberfläche, der Interpreter und der Compiler. Außerdem muß auch die Anbindung des DisCo-Systems an Standards und vorhandene Entwurfswerkzeuge angesprochen werden. Anders gesagt, findet eine Unterscheidung statt zwischen dem, wie eine Spezifikation unter DisCo stattfinden kann und dem, wozu eine solche Spezifikation innerhalb und außerhalb des DisCo-Systems verwendet werden kann. Somit ergeben sich zwei Blöcke als Evaluationsgrundlagen: Abbildung 4-1: Bereiche der Evaluation DisCo-Tool Darstellung & Animation Semantik & Ausführungsmodell Syntax & Semantik Verifikation & Simulation & Test 2. Werkzeug 1. Sprache Wie wird in DisCo spezifiziert? Wozu dient eine DisCo-Spezifikation? Andere Entwurfswerkzeuge Eine wertende Analyse des DisCo-Tools, die im Rahmen der Arbeit stattfinden soll, kann sich auf Grund der Tatsache, daß es sich bei dem DisCo-System nur um eine prototypische Implementierung handelt, eigentlich nur auf Block 1 von Abb.4-1 beziehen. Nur im Block 1 können schließlich die Maßstäbe angelegt werden, mit denen Spezifikationssprachen im allgemeinen gemessen werden. Der Block 2 hingegen umfaßt zusätzliche Optionen, die zur Weiterverwendung der Spezifikation dienen. Zusätzliche Möglichkeiten zur Bearbeitung von Spezifikation (graphische Visualisierung, Animation, Testbarkeit, Weiterverwendbarkeit in anderen Werkzeugen etc.) können aber in Hinblick auf die prototypische Implementierung von DisCo immer nur eine Aufwertung des Tools bedeuten. Andererseits können durch ihre Verfügbarkeit die Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 54 besonderen Vorzüge der gewählten Syntax, Semantik und des gewählten Ausführungsmodells klarer zum Vorschein kommen. Weiter sollte bei der Evaluation des DisCo-Systems auch im Auge behalten werden, ob und wie die Entwicklerziele realisiert wurden. Eine Analyse sollte folglich Antwort auf folgende Fragen geben: 1. Werden wichtige Konzepte, die allgemein zur Einschätzung von Spezifikationssprachen dienen, von DisCo unterstützt oder zumindest ermöglicht? 2. Wie präsentiert sich DisCo gemessen an den Zielen seiner Entwickler? 3. Ist DisCo erweiterungsfähig, welche Standards und vorhandenen Werkzeuge werden unterstützt, welche Programmiermethoden werden unterstützt? 4.1 Aufstellung der Evaluationskriterien Sinn von Spezifikation ist es, ein System in seiner Funktion umfassend und korrekt zu beschreiben. Nicht jedes beliebige System, dessen Funktionalität ja ganz heterogen durch mechanische, elektronische Anteile sowie durch Software-Anteile erbracht wird, kann mit der selben Beschreibungssprache gleich gut modelliert werden. So ist ein wesentliches Merkmal von Hardware das Auftreten von Datenfluß zwischen verschiedenen, nebenläufigen funktionalen Einheiten, folglich werden Beschreibungsmöglichkeiten für solche Charakteristiken erwartet. Bei Softwareentwicklung werden hingegen syntaktische Konstrukte zur Beschreibung von Iteration oder zur Modularisierung des Programms erwartet. Wie eine Klassifikation von Beschreibungsmöglichkeiten, die beim Erstellen von Spezifikationen erwartet und gewünscht werden, stattfinden kann, wird in [GVNG94] gezeigt. Bevor eine Zusammenfassung der konzeptionellen Modelle und deren Charakteristiken folgt, wie sie in [GVNG94] dargestellt werden, sollen nochmals einige wichtige Begriffe des HW- und SW-Entwurfs erwähnt werden. 4.1.1 Hardware- und Software-Entwurf An Programmiersprachen, die zur Spezifikation von komplexen, reaktiven Systemen dienen können - und als solch eine Sprache wurde DisCo konzipiert - werden aus unterschiedlichen Richtungen Anforderungen gestellt. Hardware-Entwurf Nach dem Y-Diagramm von Gajski und Kuhn [GaKu93] lassen sich im Rahmen des Hardware-Entwurfs verschiedene Ebenen des Entwurfs angeben, die sich durch den Grad der Abstraktion bezüglich der Implementierung unterscheiden; z.B. sind dies: 1. System-Ebene, 2. Algorithmen-Ebene, 3. Operationsfolgen-Ebene. Auf jeder dieser Entwurfsebenen kann schließlich auch Spezifikation stattfinden. Auf Systemebene findet die abstrakteste Form der Spezifikation statt. Im Sinne des zergliedernden Ent- Bewertung und Analyse der Spezifikationssprache DisCo 55 4 Analyse von DisCo wurfsstils kann auf Systemebene damit begonnen werden, grobe funktionale Einheiten des Systems festzulegen, um diese auf den niederen Ebenen in feinere Strukturen mit konkreterer Funktionalität zu zergliedern. Da sowohl eine Abstraktion aus Sicht des Verhaltens, als auch aus Sicht der Struktur und der Geometrie/Physik stattfinden kann, findet die HW-Spezifikation also in einem zweidimensionalen Entwurfsraum statt (eine Dimension ist durch die „Sicht“, die andere durch die „Ebene“ gegeben). Falls darauf Wert gelegt wird, eine Klassifizierung der DisCo-Sprache in der Sprechweise des Y-Diagramm durchzuführen, stellt DisCo ein Werkzeug zur Unterstützung der Spezifikation auf den drei oben genannten Ebenen unter Sicht des Verhaltens dar. Software-Entwurf Im Software-Entwurf werden Programmiersprachen nach Paradigmen klassifiziert. Der Begriff „Paradigma“ hat im Zusammenhang mit Programmiersprachen, die Bedeutung von „Konzept“ oder „Denkschema“, das einer Sprache zugrundliegt. Ein wichtiges Paradigma in Zusammenhang mit DisCo stellt die Objektorientiertheit dar. Auch das Konzept der jointactions, wie es im DisCo-Ausführungsmodell realisiert wurde, kann als Programmiersprachen-Paradigma aufgefaßt werden. Im Rahmen dieser Arbeit soll die DisCo-Sprache anhand von Klassifizierungsmerkmalen, die sowohl auf Programmiersprachen als auch Hardware-Beschreibungssprachen bezogen werden können, untersucht werden. In [GVNG94] findet sich eine Aufstellung von konzeptionellen Modellen und deren Charakteristiken“, die Spezifikationssprachen zugrundliegen. 4.1.2 Modelltaxonomie nach Gajski Um Systeme zu beschreiben, können verschiedene Modelle herangezogen werden. Hier eine Auflistung der Modelle und deren mögliche syntaktisch/semantische Realisierungen: 1. Zustandsorientiertes Modell: Das Systemverhalten kann durch eine Menge von Zuständen und Zustandstransitionen modelliert werden. Realisierung: Endliche (hierarchische, nebenläufige) Automaten, Petri-Netze. 2. Aktionsorientiertes Modell: Das Systemverhalten kann durch die Abarbeitung aufeinanderfolgender Aktionen modelliert werden. Realisierung: Ablaufdiagramm, Datenflußgraph. 3. Strukturorientiertes Modell: Die Systemstruktur kann als eine Menge von (meist physikalischen und nicht abstrakten) Komponenten und deren Anordnung und Abhängigkeitsbeziehung zueinander, dargestellt werden. Realisierung: z.B. Netzlisten beim digitalen Schaltungsentwurf. 4. Datenorientiertes Modell: Das Systemverhalten und die Systemstruktur werden in Form von passiven oder aktiven Einheiten modelliert, die in Relation zu einander stehen. Realisierung: Entity-Relationship - Diagramme (beim Datenbank-Entwurf). 5. Heterogene Modelle: sind erweiterte Formen oder Kombinationen der obigen vier Modell-Arten: Objektorientiertes Modell, klassische Programmierspra- Bewertung und Analyse der Spezifikationssprache DisCo 56 4 Analyse von DisCo chen, Programm-Zustands - Modell. Von besonderer Bedeutung für die DisCo-Analyse sind die Modellarten 1) und 2). Aber auch Merkmale der heterogenen Modelle 5), finden sich in DisCo wieder. 4.1.3 Modell-Charakteristiken nach Gajski Zunächst nochmal der Zusammenhang der Begriffe Charakteristik und Modell. Jedes Modell kann unterschiedlich gut Merkmale wie Nebenläufigkeit oder Zeitverhalten beschreiben. Sind solche Beschreibungsmöglichkeiten in einer Sprache vorhanden, so wird das als Charakteristikum der Sprache bezeichnet. Jede Spezifikationssprache, wie Programmiersprachen (Modula, C++) oder Spezifikationssprachen für Systeme (SDL, Statecharts, DisCo) oder HW-Beschreibungssprachen (VHDL) legen ein oder mehrere Modelle, zu Grunde und weisen daher deren Charakteristiken auf. In Abb.4-2 findet sich eine Übersicht der Begriffe: Abbildung 4-2: Modelle und Charakteristiken von Spezifikationssprachen Modell Charakteristiken Nebenläufigkeit Zustandsübergang 1. zustandsorientiert Hierarchie Programmiersprachen-Konstrukte 2. aktionsorientiert Verhaltensabschluß 3. strukturorientiert Kommunikation 4. datenorientiert Synchronisation 5. heterogen Ausnahme-Behandlung Nichtdeterminismus Zeit 1. Nebenläufigkeit: Ein System kann oft als eine Menge nebenläufiger Einheiten dargestellt werden. Von Vorteil ist daher eine Beschreibungssprache, die auf einfache Weise eine Darstellung nebenläufig ausführbarer Aktionen gestattet. Nebenläufig ausführbare Aktionen, sind Aktionen, deren Abarbeitungsreihenfolge das Systemverhalten nicht beeinflußt. 2. Zustandsübergang: Zustände oder Modi, zusammen mit Transitionen können einen Überblick über den sequentiellen, zeitlichen Verlauf des Systemverhaltens geben. 3. Hierarchie: Hierarchisierung dient dazu, ein System in kleinere Subsysteme zu unterteilen, deren Funktionen unabhängig voneinander spezifiziert werden können. Hierarchisierung dient damit der Unterstützung eines strukturierten Entwurfs, indem sie top-down und bottom-up Programmerstellung ermöglicht. Bewertung und Analyse der Spezifikationssprache DisCo 57 4 Analyse von DisCo 4. Programmiersprachen-Konstrukte: Darunter sind syntaktische Konstrukte zu verstehen, wie sie in Programmiersprachen zur Verfügung stehen, z.B. Schleifen, Prozeduraufrufe, Rekursion. 5. Verhaltensabschluß: Verhaltensabschluß ist ein Begriff, der in Zusammenhang mit modularem Aufbau einer Spezifikation Bedeutung hat. Darunter sind syntaktische Konstrukte zur Beschreibung des Ausführungsendes eines Moduls zu verstehen. So kann bei Angabe eines definierten Verhaltensabschlusses vor vollständiger Spezifikation eines Moduls schon mit der Spezifikation eines darauf aufbauenden Moduls begonnen werden. 6. Kommunikation: Bei Systemen mit Nebenläufigkeit dient Kommunikation zur Beschreibung von Interaktion (Datenaustausch) nebenläufiger Einheiten. 7. Synchronisation: Bei Systemen mit Nebenläufigkeit dient Synchronisation dazu, voneinander in ihrer Anweisungs-Ausführung unabhängige Einheiten an einer vorher festgelegten Programmstelle anzuhalten, z.B. um an dieser Stelle (synchronen) Datenaustausch zwischen den Einheiten vorzunehmen (synchrone Kommunikation). 8. Ausnahme-Behandlung (exception-handling): Reaktive Systeme sind dadurch gekennzeichnet, daß sie auf Ereignisse (events), die zum Programmablauf „asynchron“ (exceptions) sind, reagieren müssen. Mechanismen zu ihrer Beschreibung fallen unter den Begriff Ausnahme-Behandlung . 9. Nichtdeterminismus: bei Systemen mit Nebenläufigkeit gibt es Aktionen, deren Abarbeitungsreihenfolge das Systemverhalten nicht beeinflußt. Da nebenläufige Aktionen aber oft durch eine Verarbeitungseinheit erledigt werden müssen, bedarf es einer Sequentialisierung der Aktionenfolge. Die Generierung der Aktionenfolge kann durch nichtdeterministische Auswahl der jeweils nächsten Aktion erfolgen. Somit ist Nichtdeterminismus notwendig, um nebenläufigesVerhalten mit sequentieller Abarbeitung zu beschreiben. Wird ein Verhalten auf diese Weise mit Nichtdeterminismus korrekt beschrieben, entspricht das der Beschreibung des nebenläufigen Systems (siehe hierzu auch [MaPn92] S.19 „Representing Concurrency by Interleaving“). Außer zur Behandlung von nebenläufigem Systemverhalten, dient nichtdeterministische Beschreibung auch dazu, Überspezifikation zu vermeiden. Ein System ist nicht von Anfang an in seinem Gesamtverhalten bekannt, erst im Laufe der Spezifikation werden die Bedingungen, z.B. für die Ausführung einer Aktion, immer stärker konkretisiert, bis aus dem nichtdeterministischen Systemverhalten das gewünschte deterministische Systemverhalten modelliert wurde. 10.Zeit: In der realen Welt werden an das zeitliche Verhalten von Systemen Anforderungen gestellt. Daher ist auch zur Beschreibung realer Systeme der Zeitfaktor eine wichtige Spezifikationsgröße. Ein Beispiel für Zeitspezifikation wäre eine Anforderung an die maximale oder minimale zeitliche Aufeinanderfolge zweier Aktionen (Zeitrahmen). Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 58 4.1.4 Sonstige Kriterien Wichtige Entwicklerziele für die DisCo-Sprache, die nicht direkt durch die obigen Spezifikationssprachen-Charakteristiken abgedeckt werden, sind: • Möglichkeit der formalen Verifikation der Spezifikation auf Grundlage von TLA , • Ausführbarkeit der Spezifikation - Animation, Simulation, Test, • Bereitstellung einer Spezifikation als Kommunikationsgrundlage zwischen Kunden und Entwickler, daher die Forderung nach einfacher anschaulicher Visualisierung der fertigen Spezifikation, • Propagierung des Interleaving-Semantik-Ausführungsmodells zur Beschreibung von reaktiven Systemen, im Gegensatz zum prozessorientierten Ausführungsmodell, sowie dessen Realisierung durch joint-actions. Es gibt noch andere wichtige Kriterien für eine Programmiersprache, die in Zusammenhang mit der Erstellung einer Spezifikation stehen, sozusagen Kriterien aus praktischer Sicht: • Unterstützung von Programmiermethoden: bottom-up, top-down-Entwurf, • Unterstützung vorhandener Werkzeuge und Standards zur Auswertung und Weiterverwendung der Spezifikation. 4.1.5 Anmerkung zu den Kriterien Es muß hier gesagt werden, daß die Merkmale und Konzepte, wie in 4.1.3 und 4.1.4 dargestellt, nicht unabhängig voneinander sind, auch wenn die Art der Auflistung diesen Eindruck erweckt. Um zu zeigen was gemeint ist, hier zwei Beispiele: • Bei Bereitstellung der Beschreibungsmöglichkeit für nebenläufiges Verhalten, ist es ebenso notwendig, daß eine ganze Menge anderer Charakteristiken (Kommunikation, Synchronisation, Nichtdeterminismus) in der Spezifikationssprache vorhanden sein müssen, um dieses eine Konzept auf eine vernünftige Basis zu stellen, also davon überhaupt Nutzen zu haben. - Denn was nützen nebenläufige Einheiten, die nicht miteinander kommunizieren können? Andererseits macht es, um bei diesem Beispiel zu bleiben, wenig Sinn, von Kommunikation zu reden, ohne vorher das Konzept der Nebenläufigkeit bereitgestellt zu haben. - Denn was soll kommunizieren, wenn nicht nebenläufige Komponenten? • Ein Entwicklerziel war es, formale Verifikation einer Spezifikation auf Grundlage von TLA zu ermöglichen. Dieses Entwicklerziel hat sich im Rahmen der Fallstudie DisCo so ausgewirkt (?), daß das Ausführungsmodell der joint-actions gewählt wurde (nicht das prozessorientierte Ausführungsmodell). Also hat hier die eine Anforderung eine andere nach sich gezogen. Wobei im nachhinein nur vermutet werden kann, daß die Ermöglichung formaler Verifikation ein primäres Ziel der DisCo-Entwickler war, und nicht etwa die Propagierung des joint-actions-Ausführungsmodells an erster Stelle stand. So betrachtet, steht am Ende beinahe „alles mit allem in Zusammenhang“. Eine Wertung des DisCo-Tools kann jedenfalls nicht auf das Abhaken vorgefundener Konzepte reduziert werden, Bewertung und Analyse der Spezifikationssprache DisCo 59 4 Analyse von DisCo um deren Quantität schließlich als Qualitätsmerkmal für diese Spezifikationssprache anzusehen. Vielmehr muß bei der Analyse darauf geachtet werden, ob Konzepte sich gegenseitig sinnvoll ergänzen und aufeinander abgestimmt sind, und ob sich schließlich das Tool und die Sprache im praktischen Einsatz bewährt hat. Sehr wohl kann aber ein „Abhaken“ der Konzepte einen Überblick geben, was durch DisCo direkt unterstützt wird, was nur ermöglicht wird und was grundsätzlich in die DisCo-Grundkonzepte nicht einordenbar ist. Erst das „Abhaken“ von vorgefundenen Konzepten und die Berücksichtigung der gegenseitigen Ergänzung vorgefundener Charakteristiken, sowie deren Vollständigkeit, und schließlich die Bewährung des Tools im praktischen Einsatz kann eigentlich zu einer vernünftigen Analyse führen. Allerdings kann eine Trennung dieser Aspekte vorallem aus Gründen der Lesbarkeit nicht konsequent geschehen. 4.2 Modelle und Charakteristiken von DisCo Programmieren von reaktiven Systemen unter DisCo stützt sich im wesentlichen auf zwei Konzepte: joint-actions und Objektorientiertheit. Es kann somit zunächst folgende Feststellung zur Einordnung von DisCo in die Modelltaxonomie getroffen werden: DisCo ist eine aktionsorientierte Sprache mit Anleihen aus objektorientierten Sprachen. Objekte sind Instanziierungen von Datenstrukturen, die aus sequentiell, parallel und hierarchisch angeordneten Zustandsmarken, sowie variablen und konstanten Parametern bestehen. Die Objekte können an Aktionen beteiligt werden. In den Aktionen werden Zustandstransitionen und Parameteränderungen der Objekte vorgenommen. Daher kann DisCo auch als zustandsorientiert (impliziert die Charakteristik Zustandsübergang) bezeichnet werden. 4.2.1 Nebenläufigkeit, Nichtdeterminismus und Objektorientiertheit Nebenläufigkeit Das Ausführungsmodell von DisCo ist das der Interleaving-Semantik. Realisiert wurde dieses Ausführungsmodell durch das joint-actions-Konzept. Während aber die Kriterien nach Gajski [GVNG94], die oben zitiert wurden, relativ einfach zur Analyse von Spezifikationssprachen verwendet werden können, die vom Prozessbild ausgehen, gibt es zunächst einmal Schwierigkeiten bei ihrer Anwendung auf eine Sprache, der ein grundlegend anderes Paradigma zugrundeliegt. Deswegen stellt sich die Frage, wie der Zusammenhang zwischen joint-action und Prozessen ist. Um den Zusammenhang herauszustellen und zu zeigen, daß die obigen Begriffe eine wichtige Grundlage für eine Analyse sein können, soll ein Beispiel für die Übertragung von Prozessen auf joint-actions gebracht werden. Das Beispielprogramm besteht aus zwei nebenläufigen Prozessen. Die in Abb.4-3 verwendete graphische Darstellungsart für nebenläufige Prozesse wird in [MaPn92] entwickelt - und ist ohne weiteres verständlich. Das Programm in Abb.4-3 (s. [MaPn92] S.17) dient zur Berechnung des Binomialkoeffizienten mittels zweier nebenläufiger Prozesse. Es besitzt als ganzzahlige Parameter y1, y2, k , n und b. Als Eingabe-Parameter dienen n und k. Der Parameter b enthält nach Ablauf des Programms den Wert des Binomialkoeffizienten „n über k“. Der Pro- Bewertung und Analyse der Spezifikationssprache DisCo 60 4 Analyse von DisCo zeß P1 besitzt vier Zustandsmarken (l0 bis l3) und vier Transitionen (t0 bis t3), der Prozeß P2 besitzt fünf Zustandsmarken (m0 bis m4) und fünf Transitionen (r0 bis r4). Der Programmzustand zu einem Berechnungsschritt wird also definiert durch ein Paar von Zustandsmarken und den Werten der ganzzahligen Parameter. Zu Anfang ist das Programm im Zustand (l0, m0), und es gilt: n>k>=0, y1=n, y2=1, b=1. Nach einem Schritt kann sich das Programm in (l0,m1) oder (l1,m0) befinden usw. Die Transitionen ti,ri; i=0,1,... enthalten Variablen-Abfragen (Transitionsbedingungen) und Anweisungen (Parameterzuweisung). Ist eine Transitionsbedingung erfüllt, so kann ein Zustandswechsel im Prozeß stattfinden. Das Programm ist beendet, sobald sich P1 in l3 und P2 in m4 befinden. Es fällt auf, daß die Variable y1 den Zweck hat, Kommunikation, bzw. Synchronisation zwischen den beiden Prozessen zu realisieren. Denn y1 wird von beiden Prozessen lesend und schreibend referenziert. Abbildung 4-3: Beispielprogramm mit prozessorientiertem Modell - P1 - Start l0 t3: (y1<=(n-k))? l3 - P2 - Start m0 t0: (y1> (n-k))? r4:(y2>k)? m4 r0: (y2<=k)? m1 l1 t1: b:=(b*y1) r1: ((y1+y2)<=n)? m2 l2 t2: y1:=y1-1 r2: b:=b div y2 m3 r3: y2:=y2+1 Die Übertragung aus dem prozessorientierten Bild in das joint-actions-Bild kann nun so geschehen, daß die Transitionen (ti,ri; i=0,1,...) aus den Prozessen mit den DisCo-actions identifiziert werden. Außerdem muß eine geeignete Wahl der Klassen vorgenommen werden. Wie dabei vorgegangen wurde, zeigt Listing 4-1. Im System Binomial wird eine Klasse Binom definiert, diese enthält alle ganzzahligen Parameter und zusätzlich die Information, die im Prozessbild durch die Zustandsmarken (li,mi; I=0,1,...) gegeben ist. Die Nebenläufigkeit der beiden Prozesse spiegelt sich in der Angabe von parallelen Zuständen (state *L0, L1, L2, L3 parallel zu den Zuständen state *M0, M1, M2, M3, M4) wieder. Was die Konstruktion der actions anbelangt, so wird im Prinzip jeder Transition aus Abb.4-3 eine action zugeordnet. Allerdings kommt es im Prozessbild ausgehend von einer Zustandsmarke auch zu Verzweigungen (so ist bei l0 t0 oder t3 möglich), solche Verzweigungen wurden im Beispiel nun in einer DisCo-action zusammengefaßt. Allen DisCo-actions ist gemeinsam, daß sie als Bewertung und Analyse der Spezifikationssprache DisCo 61 4 Analyse von DisCo einzigen Teilnehmer ein Objekt vom Klassentyp Binom haben und als Aktionsbedingung jeweils abfragen, ob sich das Programm im vorhergehenden Zustand gemäß dem Modell in Abb.4-3 befindet. So ist bei action t03 das Teilnehmerobjekt („by Bin:Binom“) vom Typ Binom, diesem wird der Teilnehmername Bin zugeordnet. An Bin wird nun die Bedingung gestellt, daß es sich im Zustand L0 befindet („when Bin.L0 do“). Ist die Bedingung erfüllt, so kann die action schalten. Für action t03 bedeutet das, daß in Abhängigkeit vom Parameterwert y1 („if (Bin.y1 > (Bin.n - Bin.k)) then“) ein Zustandsübergang nach L1 („-> Bin.L1“) oder nach L3 („-> Bin.L3“) stattfinden kann. Die anderen actions kommen ebenso durch einfache Übertragung der Transitionen zustande. Zum creation-part des DisCo-Programms („creation RUN_Binomial of Binomial is“) ist zu sagen, daß dort die Instanziierung eines Objekts vom Klassentyp Binom geschieht. Die Werte der Parameter n und k werden durch die Anweisung „new Binom(100,33)“ auf 100 und 33 gesetzt, es soll also die Berechnung des Binoms „100 über 33“ stattfinden und in b abgelegt werden. Listing 4-1: system Binomial is class Binom (n,k : integer) is y1 : integer := n; y2 : integer := 1; b : integer := 1; state *L0, L1, L2, L3; state *M0, M1, M2, M3, M4; end; action t03 by Bin:Binom is when Bin.L0 do if (Bin.y1 > (Bin.n - Bin.k)) then -> Bin.L1; else -> Bin.L3; end if; end t03; action t1 by Bin:Binom is when Bin.L1 do Bin.b := (Bin.b * Bin.y1); -> Bin.L2; end t1; action t2 by Bin:Binom is when Bin.L2 do Bin.y1 := Bin.y1-1; Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 62 -> Bin.L0; end t2; action r04 by Bin:Binom is when Bin.M0 do if Bin.y2 > Bin.k then -> Bin.M4; else -> Bin.M1; end if; end r04; action r1 by Bin:Binom is when Bin.M1 and ((Bin.y1 + Bin.y2) <= Bin.n) do -> Bin.M2; end r1; action r2 by Bin:Binom is when Bin.M2 do Bin.b := Bin.b / Bin.y2; -> Bin.M3; end r2; action r3 by Bin:Binom is when Bin.M3 do Bin.y2 := Bin.y2 + 1; -> Bin.M0; end r3; end; creation RUN_Binomial of Binomial is new Binom(100,33); end; Selbstverständlich ist die hier gezeigte Übertragung von Prozessen auf joint-actions sehr mechanisch, und die joint-actions-Lösung ist durch die Zustandsmarken li,mi; I=0,1,... beinahe deterministisch und damit nicht ganz im Sinne einer DisCo-Spezifikation. Es sollte hier aber allein auf die Machbarkeit einer solchen Übertragung vom prozessorientierten- zum jointactions-Modell hingewiesen werden. Somit kann festgestellt werden: Nebenläufigkeit von Systemverhalten ist in DisCo durch die nichtdeterministische Generierung von Folgen von atomaren Aktionen (joint actions) zu beschreiben. Wird weiter bedacht, daß das in [MaPn92] benutzte Modell zur Beschreibung nebenläufiger Prozesse eine Syntax von nebenläufigen „endlichen“ Automaten mit der Erweiterung um Bewertung und Analyse der Spezifikationssprache DisCo 63 4 Analyse von DisCo lokale Integer-Variablen ist, und daß in DisCo umfangreiche Methoden zur hierarchischen Gliederung von Klassen zur Verfügung stehen (siehe Kap.4.2.4), kann die Feststellung getroffen werden: Das joint-actions-Modell kann zur Beschreibung Automaten mit lokalen Variablen dienen. hierarchisch nebenläufiger Nichtdeterminismus Da DisCo-actions keine Prioritäten besitzen können, durch welche die Auswahlen der jeweils nächsten Aktion einschränkt oder festgelegt werden, kann schließlich folgende Feststellung zu Nichtdeterminismus in der DisCo-Spezifikationssprache getroffen werden: Nichtdeterminismus ist dem Ausführungsmodell der Interleaving-Semantik (und deren Realisierung in Form der joint-actions) inhärent. Nichtdeterministische Beschreibung von Systemverhalten ist sozusagen die zugrundeliegende Technik bei der Erstellung einer DisCo-Spezifikationen. Objektorientiertheit Wie oben schon mehrmals erwähnt, bietet DisCo Ansätze zur objektorientierten Spezifikation. Den Zuständen von Objekten kann konkrete Bedeutung gegeben werden. Erleichtert wird die Formulierung von konkreten Zuständen durch Klassen, die strukturell wie Statecharts aufgebaut sind. Als Beispiel - eine Anforderung die natürlichsprachlich lauten würde: „Eine nicht gesicherte Aufzugskabine darf erst losfahren, wenn die Kabinentüren, die zur Kabine gehören geschlossen sind.“ , kann in DisCo durch eine action losfahren wie folgt beschrieben werden: Listing 4-2: action losfahren by K:KABINE, T:KABINENTUER is when (K=T.K and K.NICHT_EINGERASTET and T.ZU) do ->K.FAHREND; end; Als Teilnehmer besitzt losfahren ein Objekt vom Klassentyp KABINE und ein Objekt vom Klassentyp KABINENTUER. Diesen Objekten werden die roles K und T zugeordnet. Die Aktionsbedingung lautet nun entsprechend der obigen natürlichsprachlichen Formulierung „(K=T.K and K.NICHT_EINGERASTET and T.ZU)“. Ist die Aktionsbedingung erfüllt, kann ein Zustandsübergang stattfinden „->K.FAHREND“, d.h. die Kabine kann in den fahrenden Zustand übergehen. Wie das Beispiel veranschaulicht, kann sicher festgestellt werden: DisCo bietet einfache Möglichkeiten objektorientierter Programmierung. Eine relativ verständliche und einfache Übertragung natürlichsprachlicher Spezifikation in Programmcode ist gewährleistet. Nun wurden drei Charakteristiken angesprochen; an diesem Punkt stellen sich mehrere Fragen zur selben Zeit, um einige zu nennen: • “Wie können Objekte untereinander kommunizieren? - Sie existieren ja zur selben Zeit, und sind somit in gewissem Sinne parallel.“ Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 64 • „Wie sieht es überhaupt mit dem Zeit-Begriff in DisCo aus?“ • „Können Zeitrahmen in DisCo formuliert werden?“ • „Welche Rolle spielt Vererbung, die ein wichtiges Charakteristikum der Objektorientiertheit darstellt, in DisCo?“ • „Welche anderen Hierarchisierungs- oder Modularisierungsmethoden gibt es in DisCo?“ 4.2.2 Kommunikation, Synchronisation und Exceptionhandling Die einzige zustandsändernde Instanz in DisCo ist das action-Konstrukt, folglich können auch nur dort Informationen zwischen unterschiedlichen Objekten ausgetauscht werden. Nur dort können die Objekte also kommunizieren. „Kommunikation“ besteht also im Angleichen von Parameterwerten mit Hilfe von Zuweisungsanweisungen. Andere abstraktere Formen der Kommunikations-Modellierung gibt es in DisCo nicht. So kann festgestellt werden: Kommunikation mittels shared memory oder message passing zwischen Objekten gibt es in DisCo nicht. Kommunikation zwischen Objekten ist nur durch gemeinsame Teilnahme an einer Aktion möglich, dort kann eine Angleichung von Parameterwerten stattfinden. Allgemeiner läßt sich sagen, es gibt in DisCo keinerlei abstrakte Methoden zur Beschreibung von Kommunikation. Eng mit dem Begriff der Kommunikation verknüpft, ist der Synchronisations-Begriff und das Exceptionhandling. Techniken zu deren Beschreibung werden in DisCo nicht explizit unterstützt. Wie schon angedeutet, sind diese Begriffe sehr eng mit dem Prozessbegriff verknüpft und finden daher im joint-actions-Ausführungsmodell keine Entsprechung. Es kann daher festgestellt werden: Die Begriffe „Exceptionhandling“ und „Synchronisation“ als Hilfstechniken zur Spezifikation nebenläufiger Systeme können nicht unmittelbar auf Spezifikation mit Hilfe des joint-action-Modells angewendet werden und haben damit in der DisCoSpezifikationssprache keine direkte Entsprechung. Selbstverständlich, wenn hier gesagt wird, das eine oder andere Charakteristikum sei in DisCo nicht vorhanden oder würde durch DisCo nicht unterstützt, soll das heißen, daß kein direkter oder äquivalenter Begriff hierfür in DisCo existiert. Eine Art Simulation durch geschickte Programmierung dieser Mechanismen kann dennoch oft stattfinden, wie das ja schon die Realisierung des Aufzugsystems in Kap.3 gezeigt hat. Dort wurde eine Datenstruktur mit Bezeichner „Event“ kreiert, mit deren Hilfe zumindest Eventsteuerung „vorgetäuscht“ wurde. Allerdings bleiben davon die obigen Aussagen zu den hier betrachteten Charakteristiken unberührt, denn es kann nicht die Rede davon sein, daß DisCo solche Verhaltenbeschreibungen durch spezielle Sprachkonstrukte aktiv unterstützt oder erleichtert. 4.2.3 Zeit und Parallelität In Zusammenhang mit der Modellierung von Nebenläufigkeit spielt die Beschreibung des gleichzeitigen Eintretens von Ereignissen eine Rolle, d.h. die Modellierung von Parallelität. Bewertung und Analyse der Spezifikationssprache DisCo 65 4 Analyse von DisCo Hierzu muß ersteinmal geklärt werden, wie „Zeit“ in DisCo behandelt wird. Zeit = lokale Uhren für Objekte Zunächst kann die Feststellung getroffen werden: In DisCo gibt es auf der Ebene der Syntax und Semantik den Begriff Zeit nicht. Durch die Generierung von Aktionenfolgen, die ja schließlich Modelle für das Systemverhalten sind, werden noch keine zeitlichen, sondern nur logische Abfolgen von Aktionen vorgegeben. Es muß daher zwischen logischer und zeitlicher Abfolge der Aktionen unterschieden werden. Der DisCo-Interpreter dient zur Generierung von logischen Abfolgen von Aktionen. Darauf aufbauend, wurde die Betrachtung zeitlicher Abläufe folgendermaßen ermöglicht. Jedes Objekt erhält einen zusätzlichen ganzzahligen Parameter cl (clock), einen Zähler, dem die Bedeutung einer lokalen Uhr gegeben wird. Jedes Objekt besitzt also eine eigene Zeit, die mit den Zeiten anderer Objekte irgendwie synchronisiert werden muß. Die Synchronisation der lokalen Uhren geschieht durch gemeinsame Teilnahme an Aktionen. Jede Aktion erhält zunächst zwei zusätzliche Ganzzahl-Variablen: dur (duration) und st (start-time), mit der Bedeutung von Aktionsausführungszeit und Startzeit. Der Aktionsausführungszeit wird ein Wert >0 durch den Programmierer zugewiesen. Die Startzeit ergibt sich als das Maximum der lokalen Zeiten der Teilnehmer. Die Ausführungszeit der Aktion ist natürlich für alle Teilnehmer-Objekte gleich. Außerdem wird jede Aktion noch um Zuweisungsausdrücke erweitert, die die aktuelle Zeit nach der Aktionsausführung, die als Summe dur+st defniert ist, in die clParameter schreiben. Somit sind die lokalen Uhren der Teilnehmer nach der Aktionsausführung synchronisiert. Das Beispiel in Abb.4-4 zeigt drei Aktionen A1, A2, A3 und zwei Objekte x1 und x2. An A1 und A2 nimmt x1 teil, und an A3 nimmt x2 teil. Bildteil 1. zeigt eine logische Abfolge, wie sie sich aus den Aktionsbedingungen ergeben hat. Zu jedem Programmschritt wird also eine Aktion geschaltet. Bildteil 2. zeigt eine zeitliche Interpretation des Ablaufs. Jedem Objekt wurde eine lokale Uhr gegeben, diese Uhr wird jeweils um eine Zeiteinheit heraufgesetzt, wenn das Objekt an Aktion A1, A2 oder A3 teilnimmt. Wird davon ausgegangen, daß die logische Abfolge 1. der Aktionen generiert wurde, so ergibt sich die zeitliche Abfolge wie in 2. dargestellt. Also, da an A1und A3verschiedene Objekte teilgenommen haben, schaltet A3 zeitgleich mit A1, und damit vor A2, obwohl sie logisch erst „nach“ A2 geschaltet wurde. Abbildung 4-4: Logischer Ablauf und zeitlicher Ablauf 1. logischer Ablauf: A2 A1 X1 X2 A3 1 2. zeitlicher Ablauf: X1 X2 2 3 Programmschritt 3 Zeitschritt A2 A1 A3 1 2 Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 66 Die Ausführungszeit, die ja äquivalent mit der Sperrdauer der Teilnehmerobjekte ist, ist eine Eigenschaft einer Aktion und nicht eines teilnehmenden Objekts! Das ist bei genauerer Betrachtung eine zweifelhafte Festlegung, denn verschiedene Teilnehmer können selbstverständlich unterschiedlich oft referenziert werden. Während der eine Teilnehmer beispielsweise nur lesend in einer Aktionsbedingung referenziert wird, wird ein anderer eventuell lesend und schreibend im Aktionsausführungsteil referenziert. Alle Teilnehmer bleiben aber, unabhängig von ihrer Bedeutung, für die gesamte Ausführungszeit der Aktion gesperrt. Die Schwäche dieser Zeitbehandlung wird anschaulich, wenn nochmals das Beispiel, dem das Listing 4-1 zugrundeliegt, betrachtet wird. Dort ging es um die nebenläufige Berechnung des Binomialkoeffizienten. In dem System Binomial wurde nur eine Klasse Binom definiert, von dieser Klasse wiederum ein Objekt instanziiert. Auf dieses eine Objekt wird nun in jeder Aktion zugegriffen, d.h. jede Aktion „sperrt“ das Objekt für alle anderen Aktionen, somit wäre das durch Listing 4-1 spezifizierte Verhalten im Sinne der lokalen Uhr des Binom-Objekts rein zeitlich-sequentiell. Also wäre keinerlei parallele Verarbeitung beschrieben worden! Daher kann sicher die Feststellung getroffen werden: Ausführungszeit als Eigenschaft einer Aktion, die gleichzeitig eine einheitliche Sperrfrist (gesperrt für die Teilnahme an anderen Aktionen) für alle Teilnehmerobjekte bedeutet, ist zweifelhaft. Sperrfristen sollten stattdessen von der Art und Häufigkeit der Referenzierung eines Teilnehmerobjekts in einer Aktion abhängig sein. System und Realzeit-System Der Vorgang, lokale Zeiten in Form von zusätzlichen Ganzzahlparametern zu einem fertig spezifizierten System hinzuzufügen, geschieht auf die in Abb.4-5 dargestellte Weise. Zunächst wird das System programmiert, dann wird in der Regel ein Compiler-Schritt durchgeführt, der zu einem Laufzeitsystem RUN-System in Lisp-Darstellung führt. Dieses kann ausgeführt werden. Bis dahin wurden keine Zeitbetrachtungen durchgeführt. Verhält sich das System wie gewünscht, kehrt der Programmierer zur Spezifikation System zurück und führt, soweit er Zeitbetrachtungen hinzunehmen möchte, einen automatisierten Superposition-Schritt durch. Dadurch wird eine neue DisCo-Darstellung RT-System (Real-Time-System) des ursprünglichen Systems erzeugt, dieses enthält alle Spezifikationen von System. Zur Buchhaltung von lokalen Zeiten enthält RT-System zusätzlich die oben beschriebenen Komponenten in den Klassendefinitionen und zusätzliche Anweisungen zur Berechnung und zum Neusetzen der lokalen Zeiten in den Aktionen. Der Programmierer muß nun noch die Ausführungsdauern in Form konstanter Parameter für die einzelnen Aktionen festlegen und in den Quelltext eintragen. Dann wird RT-System einem Compiler-Schritt unterzogen, was zu einem Laufzeitsystem RUN-RT-System führt, dieses kann dann ausgeführt werden. Bewertung und Analyse der Spezifikationssprache DisCo 67 4 Analyse von DisCo Abbildung 4-5: Realzeit in DisCo ohne Zeit DisCo-Darstellung System Superposition- RT-System Schritt Compiler-Schritt Compiler-Schritt Lisp-Darstellung mit Zeit RUN-System RUN-RT-System Somit kann folgende Feststellung getroffen werden: Es gibt auf der Ebene der Simulation und Animation ein Hilfskonstrukt (lokale Zeiten für Objekte), das einen Realzeitbegriff auf ein fertig spezifiziertes System aufsetzt (siehe hierzu auch die Ausführungen in [KSuS91]). Startzeiten von Aktionen, die durch die oben definierten aktuellen Zeiten definiert sind, legen auf der Menge ausgeführter Aktionen einer logischen Aktionenfolge, eine zeitliche Teilordnung fest. Es existieren nur Relationen zwischen abhängigen Aktionen. Abhängige Aktionen sind Aktionen, die in der logischen Abfolge auftauchen und gemeinsame Teilnehmer-Objekte haben. So sind die Aktionen A1 und A2 in Abb.4-4 abhängig voneinander, während die Aktionen A3 und A1voneinander unabhängig sind. Beispiel Abb.4-6 zeigt eine logische Abfolge von neun Aktionen, diese sind links aufgelistet, auf der rechten Seiten werden einige der Relationen der abhängigen Aktionen durch Pfeilverbindungen angezeigt. So folgt zeitlich (bei Generierung der logischen Berechnungsfolge wie auf der linken Seite gezeigt) 2. auf 1. , während sowohl 3. als auch 4. auf 2. zeitlich folgen, bzw. 3. und 4. gleichzeitig abgearbeitet werden können. Abbildung 4-6: Logischer Ablauf und partielle Ordnung 1. logischer Ablauf: 1. action A1 by x1, x2 2. action A2 by x2, x3 3. action A1 by x3, x4 4. action A3 by x1, x2 5. action A1 by x2, x3 6. action A1 by x3, x4 7. action A1 by x1, x2 8. action A2 by x2, x3 9. action A1 by x1, x2 2. partielle Ordnung: 1. A1 2. A2 3. A1 4. A3 5. A1 6. A1 7. A1 8. A2 9. A1 Somit ergibt sich aus jeder logisch generierten Berechnungsfolge, sozusagen automatisch, eine zeitliche Ordnung auf den Aktionen. Wie die partielle zeitliche Ordnung nun aussieht, wird Bewertung und Analyse der Spezifikationssprache DisCo 68 4 Analyse von DisCo also im wesentlichen durch das Scheduling (Vorgehensweise bei Auswahl von Aktionen) bestimmt. Beweis der Korrektheit von mit DisCo spezifizierten, realen Systemen Im Falle des DisCo-Scheduling wird von undelayed scheduling gesprochen, da alle Berechnungsfolgen mit der kleinsten möglichen Startzeit für die nächste ausgewählte Aktion generiert werden. Dagegen wird in realen Systemen maximale Parallelität - maximum parallelism - der auszuführenden Aktionen gefordert, was eine stärkere Bedingung an den Scheduler darstellt. Denn maximale Parallelität erlaubt nur solche Berechnungsfolgen mit frühest möglicher Startzeit für die nächste Aktion. Hier ein Beispiel zur Veranschaulichung des Unterschieds. Abb.47 zeigt vier Aktionen und drei mögliche Berechnungsfolgen. Es soll gelten, daß die Aktion A3 erst durch Ausführung von A1 ermöglicht wird und durch die Ausführung der Aktion A4 gesperrt wird. Also ergeben sich mögliche Berechnungsfolgen 1., 2. und 3., wobei die Aktions-Ausführungszeiten variiert wurden. Maximale Parallelität erfordert nun, daß mit der Ausführung einer Aktion zum frühest möglichen Zeitpunkt begonnen wird. Das bedeutet aber, daß Berechnungsfolge 3. in Abb.4-7 unter der Bedingung maximaler Parallelität nicht möglich ist. Denn nach Ausführung der Aktion A1 wäre schon die Ausführung von A4 (frühest möglicher Zeitpunkt für das Schalten einer Aktion!) möglich und müßte somit geschaltet werden, in 3. wird allerdings eine Verzögerung in Kauf genommen, um dann mit Aktion A3 fortzufahren. Abbildung 4-7: Undelayed scheduling und maximale Parallelität 1. 2. X1 X2 X1 X2 A2 A1 A4 Zeit A2 A3 A1 A4 Zeit 3. X1 X2 A2 A3 A1 A4 Zeit Verzögerung Wie dieses Beispiel veranschaulichen soll, enthält die Menge der logischen Berechnungsfolgen, die durch das undelayed scheduling impliziert ist, auch alle Berechnungsfolgen, die den stärkeren Bedingungen von maximaler Parallelität standhalten. Das hat Auswirkungen auf die Bedeutung von Korrektheitsbeweisen auf Basis von DisCo-Spezifikationen realer Systeme. Kann der Nachweis des korrekten Verhaltens der logischen Berechnungsfolgen, ausgehend von DisCo-Spezifikation, erbracht werden, impliziert dies auch die Korrektheit von Berechnungsfolgen, die den stärkeren Bedingungen maximaler Parallelität genügen. Und dieses Verhalten ist wiederum ein Modell für reale Systeme. Die Entwickler von DisCo weisen in diesem Zusammenhang darauf hin, daß DisCo-Spezifikation (und im weiteren Sinne das Ausführungs- Bewertung und Analyse der Spezifikationssprache DisCo 69 4 Analyse von DisCo modell der joint-actions) geeignet sei, beweisbare Spezifikationen von Realzeitsystemen zu liefern [KSuS91], entgegen anders lautenden Aussagen. Zur Modellierung von Realzeitsystemen kann daher folgende Feststellung getroffen werden: DisCo kann zur Modellierung von Realzeit-Systemen und zur Beschreibung von echt parallelem Systemverhalten dienen, indem jedem Objekt eine lokale Uhr in der Form eines ganzzahligen Parameters hinzugefügt wird. Insbesondere kann (nach Aussage der DisCo-Entwickler) folgendes festgestellt werden: Auf der Grundlage von DisCo-Spezifikationen können Korrektheitsbeweise von Spezifikationen realer Systeme durchgeführt werden. Spezifikation von Zeitrahmen in DisCo Zeitargumente können insbesondere dazu dienen, die Einhaltung von Zeitrahmen zu untersuchen, hierzu zwei Beispiele. Zuerst soll gezeigt werden, wie die Forderung nach maximaler Ruhezeit eines Objekts formuliert und dann auch verifiziert werden kann. Die Ruhezeit sei die Differenz von Startzeit einer Aktion und lokaler Zeit des Objekts. Es soll also spezifiziert werden, daß ein Objekt mindestens alle ∆t Zeiteinheiten an einer Aktion teilnimmt. Sei der Einfachheit halber angenommen, daß das System nur aus einer Klasse KLASSEx und einer Aktion A bestehe. Die Aktion A wird nun in Listing 4-3 mit den notwendigen Ergänzungen für die Zeitbehandlung gezeigt; die nicht interessierenden Teile von Bedingungsteil und Anweisungsteil werden natürlichsprachlich gebracht: Listing 4-3: action A(st:integer, dur:integer) by L,R :KLASSEx; is when „sonstige Bedingungen“ and dur=1 and st=max(L.cl,R.cl) do assert (st-L.cl<6 and st-R.cl<6); „sonstige Anweisungen“ L.cl:=dur+st; R.cl:=dur+st; end; Die Variablen st, dur und cl haben die oben beschriebene Bedeutung und Funktion: Startzeit, Aktionsausführungszeit und lokale Uhr. Die Ausführungszeit der Aktion beträgt folglich eine Zeiteinheit. Hier soll gezeigt werden, wie die Einhaltung eines Zeitrahmens mit dem Wert 6 für die Teilnehmerobjekte von A überprüft werden kann. Hierzu wird im Ausführungsteil eine assert-Anweisung verwendet. Die Anweisung assert dient dazu, die Bedingung „st-L.cl<6 and st-R.cl<6“ zu überprüfen und die Programmausführung im Falle einer negativen Auswertung mit einem Fehlerhinweis abzubrechen. In diesem Fall würde die Programmausführung folglich abgebrochen, falls eines der beiden Objekte für länger als fünf Zeiteinheiten nicht mehr an einer Aktion teilgenommen hat. Da die Zeiterhöhung nur durch die Aktion A geschehen kann (A ist nach Voraussetzung die einzige Aktion im System), wird somit überprüft, ob jedes einzelne Objekt vom Klassentyp KLASSEx mindestens alle fünf Zeiteinheiten an A teilnimmt. Das ist folgendermaßen zu verstehen: die Aktion A besitzt einen Ganzzahl- Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 70 parameter st, dieser wird durch die Aktionsbedingung st=max(L.cl,R.cl) auf das Maximum der Ganzzahlparameter cl von Objekt L und R gesetzt. Die assert-Anweisung bildet nun die Differenz von Startzeit der Aktion mit den lokalen Zeiten der Objekte. Ist die Differenz größer oder gleich 6, so wird die Aktion und damit die Programmausführung abgebrochen. Die assert-Bedingung ist nur dann nicht verletzt, wenn die Teilnehmerobjekte während der vergangenen fünf Zeiteinheiten an A teilgenommen haben. Auf die hier gezeigte Weise würde natürlich noch nicht sichergestellt, daß der Zeitrahmen auch tatsächlich eingehalten wird, das könnte erst durch eine eingehende Untersuchung des Programms selbst geschehen. Das zweite Beispiel soll zeigen, wie die maximale Zeitdauer zwischen aufeinanderfolgenden Teilnahmen eines einzelnen Objekts an einer Aktion beobachtet werden kann. In Fortführung des obigen Beispiels, werde die Klasse KLASSEx folgendermaßen erweitert und die Aktion A um einige Anweisungen verfeinert: Listing 4-4: extend KLASSEx by MAX_WARTEZEIT integer :=-1; end; refined A(...) is when ... do if L.MAX_WARTEZEIT<st+dur-L.cl then L.MAX_WARTEZEIT:=st+dur-L.cl; end if; if R.MAX_WARTEZEIT<st+dur-R.cl then R.MAX_WARTEZEIT:=st+dur-R.cl; end if; ... end; Es wurde der Klasse KLASSEx also zunächst ein Parameter MAX_WARTEZEIT mit dem Initialisierungswert -1 hinzugefügt. Die Startzeit st in der Aktion A wird auf dieselbe Weise bestimmt wie oben, durch Maximalwertbildung über die lokalen Zeiten. Auch die Ausführungszeit bleibt gleich. Die Beobachtung der maximalen Wartezeit eines Objekts vom Klassentyp KLASSEx ist nun über die Entwicklung der Werte von MAX_WARTEZEIT möglich. Denn die Variable MAX_WARTEZEIT wird immer dann auf einen neuen Wert gesetzt, wenn eine Erhöhung der Wartezeit, die durch den Wert st+dur-L.cl gegeben ist, stattgefunden hat, wobei dur als konstanter Parameter für die Ausführungsdauer der Aktion A steht. Die Gewährleistung der Einhaltung gewünschter Zeitrahmen geschieht außer durch die Art der Spezifikation des Systems selbst, durch das Scheduling. Gäbe es in DisCo Prioritäten oder Wahrscheinlichkeiten für die Auswahl der nächsten auszuführenden Aktion, so wäre ein geeignetes Scheduling möglich und damit auch die Steuerung der Einhaltung gewünschter Zeitrahmen. Daher die Feststellung: Die Verifikation von Zeitrahmen ist durch zusätzlichen Buchhaltungsaufwand in DisCo möglich. Die Sicherstellung von Zeitrahmen ist jedoch nur über Spezifikationsän- Bewertung und Analyse der Spezifikationssprache DisCo 71 4 Analyse von DisCo derungen erreichbar, obwohl auch ein geeignetes Scheduling hierzu geeignet wäre. Eine Änderung der Scheduling-Politik ist jedoch nicht ohne weiteres möglich, da keine explizite Angabe von Prioritäten oder Wahrscheinlichkeiten für die Auswahl von Aktionen in DisCo stattfinden kann. Wie obiges Beispiel zeigt, wäre auch eine zeitliche Mittelung von Parameterwerten (z.B. von MAX_WARTEZEIT) zur Abschätzung von Systemverhalten wünschenswert. In DisCo ist eine statistische Auswertung von Parametern jedoch nicht vorgesehen. Als Feststellung: Es gibt keine Unterstützung zur statistischen Auswertung von Parameterwerten in DisCo. Zeitdiagramm Auf der Grundlage eines Realzeitsystems kann mit Hilfe des DisCo-Tools ein Zeitdiagramm, wie in Abb.4-8 schematisch gezeigt, automatisch erstellt werden: Abbildung 4-8: Beispiel für automatisch erzeugtes Zeitdiagramm T1 T2 T3 T4 T5 A1 A3 A2 A3 A1 A2 A3 A1 Zeit Das Diagramm bietet einen Überblick über die zeitlich parallele und sequentielle Abarbeitung von Aktionen. Um zu einem solchen Zeitdiagramm zu kommen, muß zunächst eine logische Folge von Aktionen auf Grundlage eines RT-Systems generiert werden, das kann automatisch durch das DisCo-Tool oder benutzergesteuert geschehen. Danach kann auf der Grundlage dieser Aktionenfolge, ein Zeitdiagramm erzeugt werden. Im Beispiel Abb.4-8 sind drei Aktionen zu sehen, die verschieden gefärbt sind: A1, A2, A3. Es gibt fünf Teilnehmerobjekte T1, T2, T3, T4 und T5. Es gilt nun folgendes: an A1 kann T1 und T2 teilnehmen, an A2 kann T1, T2 und T4 teilnehmen und an A3 kann T3 und T5 teilnehmen. Nun wurde also zunächst eine Berechnungsfolge mit insgesamt acht Aktionsausführungen generiert (dreimal A1, zweimal A2 sowie dreimal A3). Das erzeugte Zeitdiagramm gibt Aufschluß darüber, welche der Aktionen parallel abgelaufen sind bzw. sich überlappen. So kann abgelesen werden, daß sich A1 und A3 am Anfang überlappen. Noch bevor A3 beendet ist, beginnt schon A2 mit der Ausführung ihrer Anweisungen (A1 dauert nicht solange wie A3). Auf diese Weise kann der Programmierer im nachhinein einen Überblick über das zeitliche Verhalten des Systems bekommen. Somit die Feststellung: Auf Grundlage eines RT-Systems kann mit Hilfe des DisCo-Tools ein Zeitdiagramm erzeugt werden. Dieses bietet eine graphische Darstellung der zeitlichen Aufeinanderfolge Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 72 und Überlappung von ausgeführten Aktionen. Inwiefern aber auf der Grundlage eines solchen Zeitdiagramms eine Modifikation der Spezifikation zur Einhaltung von Zeitrestriktionen geschehen kann, wurde im Rahmen dieser Arbeit nicht weiter untersucht. Die DisCo-Entwickler beschränken sich letztendlich auf den Hinweis, daß grundsätzlich eine Möglichkeit bestünde, Zeitrahmen in die DisCo-Spezifikation (siehe Beispiele zu Listing 4-3 und Listing 4-4) einzubauen [KSuS91], diese scheint aber zum jetzigen Zeitpunkt der DisCo-Entwicklung noch nebensächliche Bedeutung zu haben. 4.2.4 Sonstige Charakteristiken Nun noch Anmerkungen zu den aus Abb.4-2 (S.55) verbleibenden, bisher noch nicht betrachteten Charakteristiken: Verhaltensabschluß, programmiersprachliche Konstrukte und Hierarchie. Programmiersprachliche Konstrukte Programmiersprachliche Konstrukte (syntaktische Konstrukte, wie for-do-end oder while-end) sind in DisCo innerhalb der actions nicht möglich (Ausnahme: if-thenelse-Anweisung). Daher die Feststellung: Prozedurale und iterative Konstrukte entsprechen nicht dem Programmiersprachenparadigma von DisCo. Verhaltensabschluß Die Abarbeitung einer Aktion geschieht sequentiell, eine Aktion wird daher beendet, sobald die letzte Anweisung innerhalb eines Aktionsanweisungsteils abgearbeitet wurde - somit folgende Feststellung: Verhaltensabschluß innerhalb einer DisCo-Spezifikationen wird durch in sich abgeschlossene, atomare Aktionen festgelegt. Den Begriff der Endzustände gibt es in DisCo aber nicht. Hierarchisierung: top-down-Methode Ein wichtiges Hilfsmittel zur methodischen Programmierung unter DisCo bietet das Konzept der superposition zur Unterstützung der top-down Methode. Unter superposition wird zum einen die Erweiterung von Klassen (zu „extend“ siehe Anmerkungen und Beispiel auf Seite 9) und zum anderen die Verfeinerung von actions (zu „refined“ siehe Anmerkungen und Beispiel auf Seite 14) verstanden. Die Anwendung der Erweiterung von Klassen und der Verfeinerung von Aktionen, dient der top-down Hierarchisierung. Daher die Feststellung: Top-down-Programmerstellung (Hierarchisierung) wird durch Anwendung der DisCoKonzepte extension und refinement unterstützt. Hierarchisierung: bottom-up-Methode Ein weitere Strategie der hierarchischen Modularisierung ist die bottom-up Methode. Auch diese wird durch DisCo-Konstrukte unterstützt. Zum einen ist der im objektorientierten ParaBewertung und Analyse der Spezifikationssprache DisCo 73 4 Analyse von DisCo digma vorhandene Mechanismus der Vererbung (Anweisung: inherit) zu erwähnen; die Vererbung in DisCo besteht darin, daß Datenstrukturen einer Sub-Klasse in eine Super-Klasse übernommen werden. Wieter wird die Eigenschaft der Objekte einer Sub-Klasse, nämlich an bestimmten Aktionen teilzunehmen, an die Objekte der Super-Klasse weitergegeben werden. In Listing 4-5 wird ein Beispiel für Vererbung in DisCo gezeigt. Im system FUNKTIONSELEMENTE sollen Elemente spezifiziert werden, die in eine später noch zu erstellende Kabinen-Spezifikation eingebaut werden. Im system AUFZUG geschieht die Spezifikation von KABINE. Die vorspezifizierten Elemente Schalter und Licht werden aus dem System FUNKTIONSELEMENTE, das vollständig nach AUFZUG importiert wurde, in die Klasse KABINE vererbt. Objekte vom Klassentyp Schalter oder Licht müssen nun nicht mehr gesondert instanziiert werden. Im creation-part RUN_AUFZUG wird für jedes instanziierte KABINE-Objekt gleichzeitig ein Licht- und ein Schalter-Objekt kreiert. Andererseits kann jedes KABINE-Objekt an Aktionen mit Teilnehmerklassen Schalter und Licht teilnehmen. Also kann jedes KABINE-Objekt zum Beispiel an der Aktion Schalter_Ein teilnehmen. Listing 4-5: system FUNKTIONSELEMENTE is class Schalter is state gedrueckt, *nicht_gedrueckt; end; class Licht is state *ein, aus; end; action Schalter_Ein by l: Licht is when l.aus do -> l.ein; end; usw. end; system AUFZUG import FUNKTIONSELEMENTE; is class KABINE(KABINEN_NUMMER : integer) is inherit Schalter, Licht; STANDORT : integer; state *AUFWAERTS, ABWAERTS; state *HALTEND, BESCHLEUNIGEND, FAHREND, ABBREMSEND; extend HALTEND by state *EINGERASTET, NICHT_EINGERASTET end; Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 74 end KABINE; end AUFZUG; creation RUN_AUFZUG of AUFZUG is new (5) KABINE; end; Zur Unterstützung der bottom-up-Methode in DisCo gibt es desweiteren das Konzept der Modularisierung. Eine module-Definition steht auf derselben Ebene wie eine system-Definition. Module können wie Systeme in andere Systeme importiert (import) werden, dort stehen dann wiederum alle Möglichkeiten der Verfeinerung und Erweiterung der so importierten Aktionen und Klassen zur Verfügung. Auf module-Ebene können dieselben Spezifikationen wie auf system-Ebene vorgenommen werden, d.h. action-Definitionen und class-Definitionen. Zusätzlich können in Modulen export-Listen angelegt werden. Diese export-Listen werden mit einem Bezeichner versehen und enthalten eine Auflistung von Klassen- und AktionsBezeichnern und optional auch Bezeichner vom Typ stuff. Stuff-Bezeichner stehen für einen beliebigen abstrakten Datenblock, der im Modul noch nicht deklariert wurde. Erst im system, das eine export-Liste importiert, wird eine stuff-Typ konkretisiert. In der module-Definition hingegen können auf Objekte vom stuff-Typ nur bestimmte Operationen in den Aktions-Definitionen durchgeführt werden: stuff-Typ-Objekte können in Listen (sequence) oder Mengen (set) eingefügt und daraus wieder entfernt werden, hierfür stehen entsprechende DisCo-Operatoren zur Verfügung (z.B. für Listen: „liefere erstes Element einer Liste“, „liefere den Rest (außer erstes Element) einer Liste“, „füge Element am Ende einer Liste an“; für Mengen: Mengenvereinigung, Schnittmengenbildung, Maximalwertbildung). Es können selbstverständlich keine arithmetischen Operationen auf stuff-Typ Objekte ausgeführt werden. In Listing 4-6 wird ein Beispiel für die Definition eines Moduls gebracht. Es wird ein abstrakter Datentyp in einem Modul spezifiziert, der dazu dienen soll, allgemeine Strukturen (Datentyp und Aktionen) zum Schreiben und Lesen irgendwelcher Daten in einer FIFO-Schlange bereitzustellen. Wie im obigen Listing zu sehen ist, besteht der abstrakte Datentyp aus einer Export-Liste „export LesenUndSchreiben is Exportelemente. end;“, die all diejenigen Elemente enthält, die später auch im importierenden System zur Verfügung stehen sollen, das sind hier also zwei Aktionen Lesen und Schreiben, sowie ein Typ-Bezeichner Element. Die Definition dieser Exportelement geschieht außerhalb der Export-Liste in bekannter Weise. Die Anweisung „Puffer: sequence Element:=<>;“, die sowohl in der Klassen-Definition von Erzeuger als auch von Verbraucher zu finden ist, initialisiert Puffer als eine leere Liste mit null Einträgen vom „Typ“ Element. Die Aktion Lesen nimmt das vorderste Element aus der Schlange heraus (Anweisung „tail(v.Puffer)“) und weist es dem Parameter el zu. Die Aktion Schreiben nimmt einen Wert in el entgegen und fügt ihn dem Puffer über die Anweisung „e.Puffer := e.Puffer & el;“ als letztes Element hinzu. Die anderen Definitionen sollten verständlich sein. Listing 4-6: module ADT is export LesenUndSchreiben is stuff Element; Bewertung und Analyse der Spezifikationssprache DisCo 75 4 Analyse von DisCo action Schreiben, Lesen; end; class Verbraucher is state *will_lesen, will_nicht_lesen; Puffer: sequence Element :=<>; end; class Erzeuger is state *will_schreiben, will_nicht_schreiben; Puffer: sequence Element :=<>; end; action Lesen (el:Element) by v:Verbraucher is when v.will_lesen and size(v.Puffer)>0 and el=head(v.Puffer) do v.Puffer := tail(v.Puffer); end; action Schreiben(el:Element) by e:Erzeuger is when e.will_schreiben do e.Puffer := e.Puffer & el; end; end; In Listing 4-7 wird nun das Module verwendet. Verwendung eines solchen Moduls. Der abstrakte Datentyp ADT wird also in das System IRGENDWAS importiert. Der stuff-Typ der Datenstruktur Element wird durch die Anweisung „use Element(Gueltig: boolean, Wert:integer)“ als Datenstruktur deklariert mit einem boolean- und einem integer-Eintrag. Es wird durch die Anweisung „rename ...“ eine Namenszuweisung der beiden Aktionen Lesen und Schreiben zu NaechsterWert und NeuerEintrag vorgenommen. Die beiden Datenstrukturen Summe und Wert werden angelegt. Es soll folgendes geschehen: Eine Liste nimmt bestimmte ganzzahlige Werte auf, und die „gültigen“ (Gültigkeit wird durch den boolean-Wert Gueltig in der Datenstruktur Element angezeigt) Elemente in der Liste werden nach und nach im Parameter Summe.gesamt aufaddiert. Neue Einträge werden durch die Aktion Eintragen vorgenommen, dort wird das ElementObjekt in die Liste aufgenommen. Listing 4-7: system IRGENDWAS import ADT(LesenUndSchreiben); use Element(Gueltig: boolean, Wert:integer) rename Lesen as Addieren; Schreiben as Eintragen; is class Summe is hilf:integer; Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 76 gesamt:integer; end; class Wert is hilf:integer; end; refined Addieren by ... t:Summe is when ... el.Gueltig and el.Wert=t.hilf do ... t.gesamt := t.gesamt + t.hilf; end; refined Eintragen by ... t:Wert is when ... el.Wert=t.hilf do ... end; ... end IRGENDWAS; Wie das Beispiel anschaulich belegen soll, kann folgende Feststellung getroffen werden: Bottom-up-Programmerstellung wird durch Anwendung der DisCo-Konzepte module, stuff-type und export/import und durch die Objektorientiertheit von DisCo, insbesondere die Vererbung (inherit), unterstützt. Außerdem kann gesagt werden, daß durch den Einsatz von Modul-Konzepten und objektorientierten Konzepten selbstverständlich auch Wiederverwendung von einmal spezifizierten Einheiten erleichtert wird. Was zur Feststellung führt: Wiederverwendbarkeit von einmal spezifizierten Einheiten ist durch den Einsatz von Modularisierung und Verwendung von stuff-Typen ( im Sinne abstrakter Datentypen) und objektorientierter Methoden in DisCo gewährleistet. 4.3 Bewertung aus Anwendungssicht Im letzten Abschnitt wurden die grundsätzlichen Möglichkeiten, der DisCo-Sprache behandelt. Hier soll es darum gehen, wie sich diese Konzepte im praktischen Einsatz (siehe Kap.3) bewährt haben oder ob sie überhaupt Anwendung fanden. Es soll hier vorallem um die auffallenden Mängel der DisCo-Spezifikationssprache gehen, da die Vorteile der DisCo-Sprache schon durch die Angabe ihrer Möglichkeiten erschöpfend behandelt wurden. Akzeptanz der Konzepte beim Programmierer Während die Spezifikation der „Aufzugssteuerung “ in Kap.3 als objektorientiert bezeichnet werden kann (besser aber objekt-basiert), läßt sich feststellen, daß sowohl top-down als auch bottom-up Methode hier keine großartige Anwendung fanden. Das hat verschiedene Gründe, Bewertung und Analyse der Spezifikationssprache DisCo 77 4 Analyse von DisCo die sicher zum einen auf einseitige Programmiererfahrung des Autors in anderen höheren Programmiersprachen (C, Modula) zurückzuführen sind („Denken“ in Prozeduren und Funktionen), zum anderen an dem zu spezifizierenden System selbst liegt. Das Aufzugsystem besteht zum Großteil aus Elementen mit einfacher Funktionalität, die keine Hierarchisierung zulassen oder erforderlich machen. Hinzu kommt, daß DisCo’s Konzept der joint-actions einen ganz anderen Ansatz der Programmierung erfordert, wie das unter Verwendung höhere Programmiersprachen der Fall ist. Die fehlende Bereitschaft, alle Möglichkeiten, die DisCo bietet, auszuschöpfen, kann aber auch darin begründet sein, daß zum einen die vorhandenen Konzepte nicht genügend gut durch das Tool unterstützt werden, und zum anderen wichtige Konzepte (z.B. die Unterstützung von abstrakten Mechanismen zur Spezifikation von Kommunikation) zur Beschreibung von realen Systemen in DisCo fehlen, was dann auch den Nutzen der an sich wertvollen vorhandenen Konstrukte mindert. Einige auffallende Mängel bei der Programmerstellung unter DisCo, die im Beispiel der „Aufzugssteuerung“ teilweise zu einer umständlichen und unübersichtlichen Programmierung beigetragen haben, sollen nun betrachtet werden. Einige Mängel der DisCo-Sprache DisCo erhebt den Anspruch eine Sprache zur Spezifikation von komplexen Systemen zu sein. Komplexe System bestehen aus vielen nebenläufigen Komponenten. Die Formulierung von Nebenläufigkeit verschiedener funktionaler Einheiten macht nur Sinn, wenn auch Konzepte zur Formulierung von Kommunikation vorhanden sind. Hier tritt ein wesentlicher Mangel von DisCo in Erscheinung, der schon oben erwähnt wurde und hier nochmals formuliert werden soll: Der DisCo-Sprachumfang bietet keine abstrakten Konstrukte zur Kommunikationsmodellierung, d.h. zur Modellierung von Broadcast oder einfacher Nachrichtenübermittlung, was aber gerade für eventgesteuerte Systeme hilfreich wäre. Auf der Ebene der Semantik könnte ein Broadcastmechanismus durch Teilnahme beliebig vieler Objekte an einer Aktion modelliert werden. Wäre in Zusammenhang mit Kommunikationsspezifikation die Möglichkeit geboten, beliebig viele Objekte an einer Aktion zu beteiligen, so könnte Kommunikation unter diesen Objekten auf einfache Weise realisiert werden, indem alle Objekte, die Nachrichten austauschen wollen, an einer Aktion teilnehmen und dort eine Synchronisation ihrer Daten vornehmen. Somit sicher ein Mangel: Eine Aktion kann nur eine bestimmte, vorher festzulegende Anzahl von Teilnehmern haben. Es gibt also nicht die Möglichkeit beliebig vieler Aktionsteilnehmer. Davon ausgehend stellt sich natürlich die Frage, wie nun Kommunikation mit den vorhandenen Sprachelementen modelliert werden kann. Wenn umfangreiche Kommunikation über eine einzelne Aktion nicht möglich ist, müssen mehrere Aktionsausführungen hierzu dienen. Hierdurch ergibt sich sogleich eine zweite negative Charakteristik von Disco. Soll ein bestimmte Abfolge von Aktionen logisch aufeinanderfolgen, so wird ein Semaphorkonzept benötigt, das eine Unterbrechung einer komplexen Aktionenfolge unterbindet. Es läßt sich jedoch feststellen: In DisCo gibt es kein Semaphor-Konstrukt oder allgemeiner, es gibt keine Mechanismen Bewertung und Analyse der Spezifikationssprache DisCo 78 4 Analyse von DisCo zur Realisierung geschützter Abschnitten. (Unter „Abschnitt“ sei hier eine Abfolge von Aktionen gemeint.) Allgemeiner formuliert könnte auch gesagt werden: DisCo bietet keinerlei Konzepte zur Ablauf-Steuerung über mehrer Aktionsschritte hinweg. Zusammengehörige Aktionenfolgen müssen durch geeignete Aktionsbedingungen gesteuert werden, was zu unübersichtlichen Programmen führen kann. Ein wesentlicher Vorteil höherer Programmiersprachen ist die Möglichkeit, beliebige Verbunddatentypen (records, enumeration) oder Felder (arrays) zu definieren. In DisCo ist solche Typdefinition nicht möglich. Sicher kann Klassendefinition Typdefinition in manchen Fällen ersetzen, doch wäre eine grundlegende Unterscheidung von Objekttypen und „reinen Datentypen“ wünschenswert. So läßt sich als Mangel anführen: DisCo bietet außer den Klassendefinitionen keine Möglichkeit, neue strukturierte Datentypen zu definieren. Was die Unterstützung der Programmiermethoden bottom-up, top-down anbelangt läßt sich sicher folgendes sagen: DisCo bietet ein breites Programmerstellung. Spektrum vom Mechanismen zur methodischen Andererseits sind diese Methoden nur dann sinnvoll anwendbar, wenn der Programmierer einen Überblick über das Gesamt-System bewahren kann und vom Spezifikationstool in dieser Hinsicht auch unterstützt wird. In DisCo geschieht die Erstellungen der Spezifikation textuell, erst im nachhinein kann sich der Programmierer einen Überblick der spezifizierten Komponenten in Form von Statecharts-Darstellungen der Klassen, und durch Animation einer graphisch visualisierten Form des Systems, verschaffen. Was in Hinblick auf die prototypische Implementierung dem DisCo-System sicher nicht als Mangel angekreidet werden kann, ist in Zusammenhang mit umfangreichen Spezifikationen unabdingbar und wünschenswert - deswegen die Feststellung: Durch die umfangreichen Möglichkeiten von 1. Importierung von Systemen und Modulen in andere Systeme, 2. Exportierung von Klassen und Aktionen aus Modulen, 3. Erweiterung von Klassen, 4. Verfeinerung, Vererbung, Spezialisierung, Kombinierung von Aktionen 5. Umbenennung von Aktions- und Klassenbezeichnern, wird dem Programmierer eine große Anzahl von Strukturierungsmethoden geboten, die allerdings in der Praxis nicht zwangsläufig zum Einsatz kommen, da die Übersichtlichkeit des Programms durch deren Verwendung eher eingeschränkt als gewährleistet wird. Eine Möglichkeit, diese Situation zu beheben, läge eventuell in der Verfügbarkeit graphischinteraktiver Erstellung von Programmen. Graphische Darstellung steht zwar bereit, jedoch nur zur Animation der fertigen Spezifikation. Statecharts-Darstellung der Klassen ist zwar möglich, wird aber nicht als visuelles Medium zur Erstellung der Klassen und Aktionen genutzt. Graphische Eingabemöglichkeit auf das bisherige DisCo-Tool aufzusetzen wäre sicher eine Aufwertung des DisCo-Tools aus Anwendungs- Bewertung und Analyse der Spezifikationssprache DisCo 79 4 Analyse von DisCo sicht. Es lassen sich daher an der jetzigen Realisierung - rein textuelle Erstellung der Spezifikation und ihre anschließende graphische Darstellung - Zweifel anmelden: Das Konzept einer rein textuellen Spezifikation von komplexen System und der anschließenden graphischen Darstellung ist als Grundlage zur Kommunikation zwischen Entwerfer und Kunden eher von zweifelhaftem Wert, da bei Zugrundelegung der graphischen Darstellung ja jeweils ein IST-Zustand des Systems präsentiert wird, der keine unmittelbare, interaktive Veränderung zuläßt. 4.4 Weiterverwendung einer DisCo-Spezifikation Ist eine Spezifikation in DisCo erstellt kann sie zum einen im DisCo-Tool zur Animation und zum Test des spezifizierten Systemverhaltens weiterverwendet werden. Zum anderen wäre zu erwarten, daß eine Anbindung an Entwurfswerkzeuge außerhalb des DisCo-tools besteht, d.h. die Weiterverwendung der Spezifikation als Eingabe für andere DisCo-fremde Entwurfswerkzeuge möglich ist. Verwendung einer DisCo-Spezifikation außerhalb des DisCo-Tools Was die Weiterverwendbarkeit der Spezifikation in anderen Tools anbelangt, beschränkt sich diese darauf, DisCo-Spezifikationen als Grundlage zur Durchführung maschineller Korrektheitsbeweise zu benutzen. Die Idee der DisCo-Entwickler war es, eine einfach strukturierte Sprache zu schaffen, die eine unkomplizierte Übersetzung in eine formale Notation erlaubt. Insbesondere mußte bei der Wahl einer bekannten formalen Sprache darauf geachtet werden, daß der Aufbau der actions, das joint-actions-Konzept, das Ausführungsmodell der Interleaving-Semantik, sowie die Mechanismen des refinement und der extension eine Entsprechung in der formalen Sprache finden, um eine einfache Übersetzung zu gewährleisten. Zur Anwendung kamen bisher die formale Sprache TLA (Temporal Logic of Actions) [Lamp94] sowie die PVS-Darstellung (Prototype Verification System) [OwRS92]. Ein Beispiel für eine Abbildung einer DisCo-Spezifikation auf TLA wird in [Kell94] gegeben. Wie ein mechanischer Beweis auf Grundlage von PVS stattfinden kann, und wie er anhand einer Beispiel DisCo-Spezifikation durchgeführt wurde, wird in [Kell95] erläutert. Aus den Fallstudien folgt daher die Feststellung: DisCo-Spezifikationen können als eine Grundlage für die Durchführung mechanischer Korrektheitsbeweise dienen. Die DisCo-Sprache kann auf formale Sprachen (TLA, PVSDarstellung) abgebildet werden, die wiederum in Beweisgeneratoren eingesetzt werden. Andere Arten der Unterstützung von DisCo-fremden Entwurfswerkzeugen oder Möglichkeiten der Anbindung an Entwurfswerkzeuge sind nicht bekannt. Hingegegen fanden, wie oben schon angedeutet, die von Harel entwickelten Statecharts Eingang in die Art des syntaktischen Aufbaus und der Visualisierung von Klassen und Objekten. Eine Option zur Visualisierung des Gesamtsystems auf Grundlage von Statecharts ist im Tool vorgesehen, bisher aber noch nicht implementiert. Daher die Feststellung: DisCo übernimmt bei der syntaktischen Struktur und der Visualisierung von Systemkomponenten (Klassen bzw. Objekt) das Konzept der Statecharts, bisher ist Bewertung und Analyse der Spezifikationssprache DisCo 4 Analyse von DisCo 80 jedoch keine Möglichkeit vorhanden das Gesamtsystem in Statechart-Repräsentation zu visualisieren. Verwendung einer DisCo-Spezifikation innerhalb des DisCo-Tools Die Art der Anwendung und Bedienung des DisCo-Tools wurde schon in Kap.2.2 erläutert, hier soll es um auffallende Schwächen des Tools bei Durchführung von Tests, Simulation und Animation des Programms, sowie schließlich um grundlegende Mängel bei Bedienung der Benutzungsoberfläche gehen. Wie der praktische Einsatz belegt, kann zunächst die positive Feststellung getroffen werden: Das DisCo-Tool arbeitet zum aller größten Teil fehlerfrei und erwartungsgemäß in allen von den Entwicklern in der DisCo-Beschreibung erläuterten Features. Insbesondere ist die graphische Ausgabe gut realisiert, es werden umfangreiche Gestaltungsmöglichkeiten geboten (siehe auch Anmerkungen in Kap.2.3 - Kap.2.3.2). Dieser positiven Feststellung steht entgegen, daß alle Funktionen, wie das Übersetzen von DisCo- in Lisp-Darstellung, Animation und Simulation der fertigen Spezifikation, bis hin zur Layoutgestaltung, sowie der Bildschirmaufbau, sehr lange Ausführungszeiten in Anspruch nehmen. Somit läßt sich sagen: Ausführungszeiten des Compilierens, der Simulation, der Graphik-Darstellung („Bildschirmaufbau“), sowie der interaktiven Manipulation von Graphik-Objekten, sind unbefriedigend lang. Diese langen Ausführungszeiten sind leider nicht mehr nur als Mangel anzusehen, sondern beeinträchtigen gerade die Simulation (vom DisCo-Interpreter automatisch durchgeführte Berechnung von logischen Aktionenfolgen ohne Graphik-Ausgabe) und die Animation (vom DisCo-Interpreter eventuell unter Benutzerinteraktion durchgeführte Berechnung von logischen Aktionenfolgen mit Graphik-Ausgabe) derart, daß schon bei relativ kleinen Systemen, wie der erstellten „Aufzugssteuerung“, keine umfangreichen Tests möglich sind. Der Programmierer der Spezifikation muß sich dann im großen und ganzen mit der graphischen, statischen Darstellungen des Systems zufrieden geben, die eigentliche Funktionalität ist nur in ganz geringem Umfang zu erfassen, Verifikation der Korrektheit ist auf diese Weise sicher nicht möglich. Somit die Feststellung: Ein Umfangreicher Test der Systemspezifikation (Verifikation der Korrektheit) ist auf Grundlage der jetzigen prototypischen Implementierung des DisCo-Systems nicht möglich. Selbst wenn unter Benutzung von assertions oder durch das Setzen von Breakpoints bedingungsabhängige Unterbrechungen in das System eingebaut werden, oder der automatische Programmablauf durch das Auftreten eines Deadlocks unterbrochen wird, ist das Debugging unter DisCo ein Geduldsspiel, denn nachdem ein Fehler gefunden wurde, muß der gesamte berichtigte Quelltext erneut übersetzt werden, was schon bei relativ kleinen Systemspezifikationen zu lange dauert. Daher sind nicht nur den Testmöglichkeiten unter DisCo enge Grenzen gesetzt, sondern auch das Debugging nur unzureichend möglich; was zu folgender Feststellung führt: Debugging von Systemspezifikationen mittlerer und großer Systeme unter DisCo läßt nur Bewertung und Analyse der Spezifikationssprache DisCo 81 4 Analyse von DisCo erahnen, was möglich sein könnte, ist aber bisher nicht durchführbar. Ebenso steht es mit umfangreicher (automatischer) Animation. Ein anderer wesentlicher Mangel, der aber sicher nicht in der Art der Realisierung der Benutzungsoberfläche gründet, sondern auch in der DisCo-Sprache selbst, aber bei der Animation einer DisCo-Spezifikation besonders auffällt, besteht darin, daß keine Möglichkeit gegeben ist, Testdaten zu erstellen und diese beim Ablauf des Programms einzulesen. DisCo erlaubt eben nur die Spezifikation eines abgeschlossenen Systems. Das bedeutet, eine DisCo-Spezifikation umfaßt beides, die eigentliche Funktionalität des Systems und der Systemumgebung, sowie die Modellierung der Interaktion des System mit der Umgebung. Das wirkt sich dann so aus, daß keine Einflußnahme auf das System von außen zur Laufzeit möglich ist. Wünschenswert wäre es, Nachrichten und Signale an das System schicken zu können, um dessen Verhalten auf äußere Einflüsse (z.B. Störungen, Notfallsituationen) zu prüfen - das ist in DisCo nicht ohne weiteres möglich. Sollen solche externen Ereignisse berücksichtigt werden, so müssen entsprechende Spezifikationen in Form eigens definierter „Stör-Aktionen“ in das Programm aufgenommen werden. Als Feststellung bleibt: Es gibt zur Laufzeit keine Möglichkeit unterschiedliche Test-Umgebungen an das Runtime-System anzubinden und somit das Systemverhalten unter verschiedenen Bedingungen zu untersuchen. 4.5 Anmerkungen Die in Kapitel 4 vorgenommene Analyse sollte die Vorzüge und Nachteile von DisCo herausstellen. Bei DisCo handelt es sich um die Realisierung einer Spezifikationssprache mit einem nicht prozessorientierten Ansatz zur Verhaltensbeschreibung und Systemspezifikation. Es gibt vielfältige Konzepte zur hierarchischen Modularisierung von DisCo-Programmen. Die alleinige Existenz von Konzepten führt bei der praktischen Anwendung der Sprache DisCo jedoch noch nicht notwendigerweise zu deren Gebrauch. Deswegen wäre es wünschenswert, daß die Anwendung der Konzepte durch den Programmierer auch durch das DisCo-Tool unterstützt würden - Stichwort: graphische Erstellung von Spezifikationen. Die fehlende Bereitschaft DisCo-Konzepte anzuwenden kann auch darin begründet sein, daß abstraktere Konstrukte, die als grundlegende Mechanismen für jede Systemspezifikation zu erwarten wären - Stichwort: Kommunikationsmodellierung - fehlen. Es muß daher zuviel Überlegung darauf verschwendet werden, wie solche Mechanismen mit Hilfe der doch recht simplen Konzepte der DisCo-Sprache modelliert werden können. Die Eigenschaften der DisCo-Sprache, die sie als Ausgangspunkt für die Durchführung von mechanischen Korrektheitsbeweisen auszeichnet, gereichen der Sprache auf der anderen Seite, ihrer Verwendung als Spezifikationssprache für komplexe Systeme, jedenfalls aus Anwendersicht, zum Nachteil. Bewertung und Analyse der Spezifikationssprache DisCo 5 Zusammenfassung 5 82 Zusammenfassung Diese Arbeit hatte die Analyse des Spezifikationswerkzeugs DisCo zum Gegenstand. DisCo stellt eine eigene Spezifikationssprache zur Verfügung, sowie Möglichkeiten zur graphischen Visualisierung und Ausführung einer Spezifikation. Die DisCo-Sprache besitzt objektorientierte und aktionsorientierte Eigenschaften. Der Aufbau der DisCo-Objekte lehnt sich an das Modell von Statecharts an. Objekte können an DisCo-actions beteiligt sein. Diese Aktionen beruhen auf dem Konzept der joint-actions und besitzen einen Aktionsbedingungsteil und einen Aktionsausführungsteil. Dem Konzept der joint-actions inhärent ist das Ausführungsmodell der Interleaving-Semantik. DisCo stellt somit dem in vielen Spezifikationssprachen für Systeme verwendeten Prozessbild zur Verhaltensbeschreibung ein alternatives Konzept entgegen. Eine wesentliche Aufgabe der Analyse bestand nun darin, herauszuarbeiten wie auf der Grundlage der joint-actions eine Spezifikation von nebenläufigen, miteinander kommunizierenden Einheiten stattfinden kann. Die Durchführung der Analyse stützte sich zum einen auf die praktischen Erfahrungen, die durch die Ausarbeitung einer Spezifikation (Aufzugssteuerung) gewonnen wurden, zum anderen auf allgemein formulierbare Konzepte von Spezifikationssprachen. Die Spezifikation der Aufzugssteuerung wurde ausgehend von einem vorhandenen Pflichtenheft erstellt. Da den Ausführungen im Pflichtenheft im wesentlichen ein Prozessbild zugrundelag, wurde es unter Berücksichtigung der DisCo-eigenen Konzepte soweit modifiziert, daß einerseits die Anforderungen an das Systemverhalten gewährleistet waren, andererseits die Übertragung in DisCo-Syntax, unter Sichtwiese des Ausführungsmodells der InterleavingSemantik, möglich wurde. Die Evaluationskriterien, anhand derer die DisCo-Sprache untersucht wurde, umfassen allgemeine Charakteristiken zur Beschreibung von reaktiven Systemen. Es wurde versucht, trotz der auch in diesem Fall vorliegenden „Prozessnähe“ der Charakteristiken, deren Anwendung auf die DisCo-Sprache vorzunehmen. Es soll an dieser Stelle auf eine nochmalige Auflistung der Resultate verzichtet werden, stattdessen einige wichtige Aspekte genannt werden, die in dieser Analyse nicht zur Sprache kamen: • Die Einschätzung und Wertung der DisCo-Konzepte unter dem Gesichtspunkt, die DisCo-Sprache in eine formale Sprache (TLA) zu übersetzen zu wollen. Unter dieser Sichtweise würde sicherlich manche Eigenschaft der Sprache, die aus praktischer Anwendersicht eher negativ zu werten ist, als notwendig oder unabdingbar erscheinen. • Umfangreichere Überlegungen zur Entwicklung der Sprache DisCo, insbesondere Überlegungen zur formalen Sprache TLA, die ein theoretische Grundlage der DisCoSprache darstellt. • Ein umfangreicher Vergleich von DisCo mit anderen Spezifikationssprachen. Denn aus der Gegenüberstellung wäre sicher eine noch bessere Einschätzung von DisCo zu gewinnen gewesen. • Genauere Herausarbeitung von Vor- und Nachteilen von Prozessbild und jointactions-Bild. Bewertung und Analyse der Spezifikationssprache DisCo 83 Literatur Literatur [BaKS83] R.J.R. Back and R. Kurki-Suonio. „Decentralization of Process Nets with a Centralized Control.“ Distributed Computing 3, 3, May 1989, 73-87. Frühere Version in Proc. 2nd ACM SIGACT-SIGOPS Symposium on Principles of Distributed Computing, Montreal, Canada, August 1983, 131-142. [BaKS88a] R.J.R. Back and R. Kurki-Suonio. „Serializability in Distributed Systems with Handshaking.“ In Proc. ICALP 88, Automata, Languages and Programming (Ed. T. Lepistö and A. Salomaa), LNCS 317, Springer-Verlag 1988, 52-66. [BaKS88b] R.J.R. Back and R. Kurki-Suonio. „Distributed Cooperation with Action Systems.“ ACM Transactions on Programming Languages and Systems 10, 4, October 1989, 513-554. [GaKu93] D. Gajski, R. Kuhn. Guest Editors’ Introduction: New VLSI Tools. IEEE Computer, 6(12):11-14, 12/1993. [GVNG94] D. Gajski, F. Vahid, S. Narayan, J. Gong. Specification and Design of Embedded Systems. Prentice Hall, 1994. [Hare87] D. Harel. „Statecharts: A Visual Formalism for Complex Systems.“ Science of Computer Programming 8, 1987, 231-274. [JäKS89] H.-M. Järvinen, R. Kurki-Suonio. „Action System Approach to the Specification and Design of Distributed Systems.“ Proc. of Fifth International Workshop on Software Specification and Design. ACM Software Engineering Notes 14, 3 (May 1989), 581-604. [JäKS90/1] H.-M. Järvinen, R. Kurki-Suonio. „The DisCo Language and Temporal Logic of Actions.“ Tampere University of Technology, Software Systems Laboratory, Report 11, 1990. [JäKS94] H.-M. Järvinen, R. Kurki-Suonio. „The DisCo Language.“ Tampere University of Technology, Research Institute for Information Technology, Project DisCo. 03/ 1994. [JäKS91] H.-M. Järvinen, R. Kurki-Suonio. „DisCo Specification Language: Marriage of Action and Objects.“ Proc. of 11th International Conference on Distributed Computing Systems, Arlington, Texas, May 1991, IEEE Computer Society Press, 142151. [Kell94] P. Kellomäki. „Analysis of a Stabilizing Protocol: A Case Study in Reasoning about Action Systems.“ Thesis for the Degree of Licentiate of Technology. Tampere University of Technology, 1994. Bewertung und Analyse der Spezifikationssprache DisCo WWW-Seiten zum Thema 84 [Kell95] P. Kellomäki. „Mechanizing Invariant Proofs of Joint Action Systems.“ Proc. of 4th Symposium on Programming Languages and Software Tools, Visegrád, Hungary, June 1995. [KSuS91] R. Kurki-Suonio, K. Systä. „Modeling Distributed Real-Time Systems in DisCo.“ Proc of Euromicro'92 Workshop on Real-Time Systems, Athens, Greece, June 1991, IEEE Computer Society Press, 136-14. [KSSV91] R. Kurki-Suonio, K. Systä and J. Vain. „Scheduling in Real-Time Models.“ In Formal Techniques in Real-Time and Fault Tolerant Systems (Ed. J. Vytopil), LNCS 571, Springer-Verlag, 1991, 327-339. [KuSu96] R. Kurki-Suonio. „Fundamentals of Object-Oriented Specification and Modeling of Collective Behaviors.“ To appear in a forthcoming book published by Kluwer, 1996. [Lamp94] L. Lamport. „The Temporal Logic of Actions“. ACM trans. Prog. Lang. Syst., 16(3):872-923, 1994. [MaPn92] Z. Manna, A. Pnueli. The Temporal Logic of Reactive and Concurrent Systems. Springer, 1992. [OwRS92] S. Owre, J.M. Rushby, N. Shankar. „PVS: A Prototype Verification System“. In D.Kapur, editor, 11th International Conference on Automated Deduction, vol.607 of Lectures Notes in Artificial Intelligence, p.748-752. Springer-Verlag, 1992. [Syst94] K. Systä. „DisCo: User Manual. DisCo Working Paper“.Research Institute for Information Technology - Project DisCo, Tampere University of Technology, Finnland. 10/1994. WWW-Seiten zum Thema1 [WWW_1] http://www.cs.tut.fi/laitos/DisCo/DisCo-english.fm.html [WWW_2] http://www.cs.tut.fi/laitos/DisCo/ESSI.html 1.Stand 07/1996 Bewertung und Analyse der Spezifikationssprache DisCo 85 Abbildungsverzeichnis Abbildungsverzeichnis Beziehung zwischen Klasse - Objekt - Aktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Beispiel für DisCo-Aktionsreihenfolge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Auswahl von Aktionen und Objekten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Erstellung und Ausführung einer DisCo-Spezifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Anordnung von Zuständen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Beispiel für Klassendefinition - Klasse KABINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Beispiel für DisCo-Graphikausgabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Systemkomponenten eines Personenaufzugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Auftragsarten beim Personenaufzug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 Vier Aspekte des Systemverhaltens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Plan-Auswahl bei Innenauftrag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Plan-Auswahl bei Außenauftrag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 Klasse AUFZUGSSCHACHT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Klasse KABINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Klasse STOCKWERKKNOPF_INNEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Klasse RICHTUNGSKNOPF_AUSSEN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Referenzen zwischen Klasse-Plan-Auftrag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Klasse PLAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Klasse AUFTRAG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Beispiel einer Aktivität - „Broadcast nach Eingang eines Außenauftrags“ . . . . . . . . . . . . . . 50 Bereiche der Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 Modelle und Charakteristiken von Spezifikationssprachen . . . . . . . . . . . . . . . . . . . . . . . . . . 56 Beispielprogramm mit prozessorientiertem Modell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Logischer Ablauf und zeitlicher Ablauf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 Realzeit in DisCo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Logischer Ablauf und partielle Ordnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Undelayed scheduling und maximale Parallelität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Beispiel für automatisch erzeugtes Zeitdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 Bewertung und Analyse der Spezifikationssprache DisCo Ich versichere, daß ich diese Arbeit selbständig verfaßt und nur die angegebenen Hilfsmittel verwendet habe. Markus Schmid