Ist ein Automat eine Ereignissache?

1. Einleitung


Nachdem ich von maßgeblichen Lippen gehört hatte, dass „Automaten eine Ereignissache sind“ [3], wurde mir klar, dass endliche Automaten vollständig gebrandmarkt sind. Überzeugen Sie sich selbst: In der Qt-Bibliothek ist ein Ereignismodell von Automaten [1] implementiert, in UML sind sie auch [2], wir betrachten die Automaten des Simulink-Stateflow-Erweiterungspakets des MATLAB-Systems [4] (im Folgenden einfach Stateflow) und dort Ereignisse usw. usw. In diesem Zusammenhang ist die Erklärung von Ph.D. A.A. Es ist ungezogen, anders zu interpretieren, weil nichts anderes kann sein, weil es nicht sein kann.

Aber wenn Sie sich an die Theorie der endlichen Automaten (TCA) erinnern, dann ist kein Wort über Ereignisautomaten drin! Um jedoch der Theorie zu widersprechen, sind gewichtige Argumente erforderlich. Gibt es einen Grund, die Professionalität von D. Harell als Schöpfer der Notation zu bezweifeln, auf die die UML-Sprache, das Stateflow-Paket, ihre Ideen stützt, die A.A. Frech? In der Tat gibt es UML, Stateflow, SWITCH-Programmierung und andere automatische Programmieroptionen, die in gewissem Maße erfolgreich funktionieren.

Ist es also möglich, das "Stigma der Ereignisse" aus dem Finite-State-Machine-Modell zu entfernen, indem die "Schnitzel von den Fliegen" getrennt werden? Das heißt trennen die Theorie der Automaten und Rechenmodelle ähnlich wie D. Harels Modelle. Und zu bedenken, dass letztere, obwohl sie die Terminologie der Automatentheorie verwenden, nach ihrer Implementierung die Entwicklung eines Modells für Blockdiagramme von Programmen darstellen.

Anmerkung 1. In diesem Fall handelt es sich um das Programmverwaltungsmodell und nicht um das Programmmodell selbst (weitere Einzelheiten zu den Modellen finden Sie in [5]).

Denken Sie daran, dass die Qt-Bibliothek ein Ereignismodell einer Finite-State-Maschine implementiert, das aus der UML entlehnt wurde. Dasselbe Modell wird von Stateflow implementiert. Das heißt Die Quelle der Ereignisse ist UML, wo die Automaten auf der von D. Harel vorgeschlagenen Notation basieren. Letztere für die Erstellung einer solchen automatischen Programmierung zu beschuldigen, wäre aber auch nicht wahr, weil "Eventfulness" ist eine Tendenz moderner Ansätze zur Implementierung von Softwaremodellen. Es basiert auf maßgeblichen Meinungen wie den erwähnten „Maschinen sind ein Ereignis“ und der hohen Popularität von Sprachen und Technologien wie UML. Dies ist zweifelsohne das Ergebnis der Nachahmung von Maschinen gemäß den bestehenden Grundsätzen für den Betrieb von Betriebssystemen.

Aber wir wiederholen, wie es nicht seltsam erscheint, aber für einige kann es sogar zu Nachrichten werden, in der Theorie der Automaten gibt es kein Ereignismodell eines endlichen Automaten. Zumindest in dem Teil, der als klassisch angesehen wird (siehe für weitere Einzelheiten beispielsweise [6] oder [7]). Es gibt einen klaren Widerspruch zwischen Theorie und Praxis. In einer solchen Situation muss man etwas mit der Theorie anfangen oder die Praxis irgendwie beeinflussen. Aber vielleicht haben Programmierer Recht mit ihrem Wunsch, das Modell einer endlichen Zustandsmaschine zu finalisieren, indem sie das Konzept des „Ereignisses“ einbeziehen [8, 9]?

Aber wie lassen sich die Wünsche der Programmierer mit der Tatsache verbinden, dass „die größten Schwierigkeiten bei der Verwendung des Automatisierungsansatzes mit dem Verständnis der Funktionsmerkmale von Automaten in Ereignissystemen verbunden sind“ (siehe [8]). Ich möchte die Ursachen solcher Probleme verstehen und in diesem Zusammenhang Event-Maschinen und / oder deren Analoge implementieren. Zu diesem Zweck nehmen wir die Implementierung von Automaten in Qt und wiederholen sie unter Verwendung des Modells eines klassischen endlichen Automaten.

Eine solche Implementierung von Ereignisautomaten ist notwendig, um die genannten "Merkmale" zu bewerten und / oder zu überwinden. Die Anwendung des klassischen Modells wird die Theorie der Automaten auch auf die Praxis der "Ereignisprogrammierung" ausweiten. Und letztendlich wird ein Analogon, das auf einem anderen Modell basiert, nur den Anwendungsbereich von Finite-State-Machine-Modellen erweitern.

2. Ereignisse, Signale und Geschlechtsidentität von Automaten


In der UML ist ein Ereignis „ein signifikantes Phänomen, das eine bestimmte zeitliche und räumliche Position einnimmt und bestimmte Konsequenzen hat“ [10]. Ein Ereignis in der Theorie der Automaten ist eine Teilmenge der eingegebenen Zeichen, die durch die Zeichen des ausgegebenen Alphabets dargestellt werden (es gibt sogar das Konzept der Ereignisalgebra in der TCA) [6]. Dasselbe, was den Übergang eines Automaten verursacht, nennt man Eingangssignale in der Theorie der Automaten. Sie sind die Konsequenzen und „der Grund, der Übergang des Automaten von einem Zustand in einen anderen. In diesem Fall sind die Ausgangssignale die „Antwort des Automaten auf die Eingangssignale“. Beide „beziehen sich auf Zeitmomente, die durch die entsprechenden Übergänge des Automaten bestimmt werden.“ [6] In der UML ist das Signal „eine benannte Entität, die als Kommunikationsmittel dient zwischen Objekten “[10].

Die Bezeichnungen der Begriffe sind also gleich, aber die Bedeutung, die in sie investiert wird, ist unterschiedlich. Wenn Sie sie jedoch neu anordnen, können Sie eine Ähnlichkeit feststellen: Es wird deutlich, dass die Ereignisse in UML den Signalen von Zustandsautomaten in der TCA entsprechen. Aber vielleicht sind unter dem Begriff „Finite-State-Machine“ auch verschiedene Entitäten verborgen? Lassen Sie uns versuchen, es herauszufinden, beginnend mit Ereignissen ...

Der Ereignisautomat ist ein passiver Automat, weil funktioniert nur im Moment der Ankunft von Ereignissen. Im Gegensatz dazu repräsentiert der klassische Automat das aktive Modell. Es funktioniert ohne Bezug auf irgendetwas (für weitere Details zu passiven und aktiven Automaten siehe [9]). Hier bettelt die Assoziation mit zwei Läufern, wobei der erste von Tritten (Events) angetrieben wird und der zweite von alleine läuft.

Im Gegensatz zu [8] werden wir die Momente des Auftretens von Ereignissen zunächst nicht mit dem Start des Automaten verknüpfen. Wir bleiben also im Rahmen der Automatentheorie, die die asynchrone Funktionsweise von Automaten in Bezug auf die äußere Umgebung bestimmt. Es spricht nur von diskreter Zeit, in der der Zustandswechsel für eine beliebig kleine, aber nicht gleich Null liegende Echtzeitperiode durchgeführt wird. Und der Grund für die Übergänge ist der aktuelle Zustand und die Eingangssignale der Maschine, wobei die Konsequenzen die Installation eines neuen Zustands und die Werte der Ausgangssignale der Maschine sind (Einzelheiten zur Definition von Maschinen siehe [6]).

Die Automatentheorie ist flexibel bei der Bestimmung der diskreten Zeit, bei der es sich um ein Echtzeitmodell handelt. Ein diskreter Zeitzyklus kann also einen festen oder gleitenden Wert eines Echtzeitintervalls haben, und dementsprechend werden Maschinen als synchron oder asynchron bezeichnet. Gleichzeitig kann das der Uhr zugeordnete Zeitintervall einen beliebigen Wert haben, einschließlich eines unendlich kleinen Werts, der jedoch nicht gleich Null ist.

Bemerkung 2. Ein Finite-State-Machine-Modell ist eines der wenigen formalen Modelle, das in seiner Definition ein Echtzeitmodell in expliziter Form enthält.

Infolgedessen erlaubt die formal „unendliche“ Geschwindigkeit des aktiven Automaten, dass jedes Ereignis als potentielles Eingangssignal behandelt wird (im Sinne von UML entspricht Bedingung [11] diesem). Die Maschine muss nur solche Ereignisse / Signale und Pausen zwischen ihnen „erfassen“. All dies definiert tatsächlich das Protokoll für die gemeinsame Arbeit von Medium und Automat. Das Protokoll sollte auch das Problem des Erkennens nacheinander empfangener identischer Ereignisse lösen. Ohne dies können beispielsweise zwei identische Symbole, die nacheinander empfangen werden, als eins wahrgenommen werden.

Formal sind die Nuancen der Ereignisverarbeitung nicht signifikant (siehe dieselben abstrakten Automaten), aber bei der praktischen Implementierung von Algorithmen, die nach dem Typ des Ereignismodells aufgebaut sind, müssen sie berücksichtigt werden. Bei der Qt-Bibliothek ist ihre Abrechnung in den Implementierungsklassen des Automaten verborgen. Des Weiteren werden wir die Unterschiede zwischen Ereignis- und klassischen Automaten am Beispiel der Implementierung des einfachsten Rechners aus [1] berücksichtigen, wo dessen „Ereignisimplementierung“ angegeben ist. Im Gegensatz zu dieser Lösung werden äquivalente Modelle erstellt, die auf der klassischen Finite-State-Maschine basieren.

3. Rechnermodelle


Fangen wir also an ... Wir nennen Ereignissignale, gewöhnliche Automatenereignisse ... oder in umgekehrter Reihenfolge und / oder umgekehrt? Ugh! Verwirrt. Kurz gesagt, die komplette "glockige Cuzdra Shteko Budlanula" und etwas "Locken". Um herauszufinden, wer wer ist, was und wie man es nennt, ist es am sichersten, ein bestimmtes „Bokra“ auszuwählen und es zu „stoßen“ ... Das Programm „automatischer Taschenrechner“ wird weiterhin eine solche „Seite“ sein.

3.1. Aktives Rechnermodell


In Abb. 1 zeigt das Originalmodell der Klasse Calculator aus [1]. In der Erscheinung sieht es aus wie eine klassische abstrakte Maschine ohne Ausweg. Der Unterschied besteht darin, dass Qt Aktionen verknüpft, wenn es in einen Zustand eintritt und diesen verlässt. Am Ausgang werden sie durch das Signal exit () und beim Eintritt in den Zustand durch das Signal enter () ausgelöst. Wir stellen jedoch fest, dass diese Aktionen in der Grafik in keiner Weise dargestellt werden.

Wenn wir das Modell in Abb. 1 mit einem Automaten mit einem abstrakten Zustand (seine anderen Namen sind struktureller, logischer Automat), kann man leicht sehen, dass die Aktionen am Ausgang des Zustands den Signalen des Mealy-Automaten entsprechen und die Aktionen am Eingang zu ihm den Signalen des Moore-Automaten entsprechen.
Bemerkung 3. In Anbetracht der Software-Implementierung des Modells werden wir nicht über Signale, Ereignisse, Bedingungen usw. sprechen, sondern über die Aktionen von Automaten, vorausgesetzt, dass sie auf Programmebene bestimmten Programmaktionen zugeordnet sind, die im Allgemeinen der Fall sind dargestellt durch Softwarefunktionen.

Der sogenannte kombinierte Mili-Moore-Automat (oder ein anders gemischter Automat [12]), der dem Automaten in Abb. Fig. 2 zeigt die Funktionen, die den Eingangs- und Ausgangssignalen des Automaten entsprechen.

Bild
1. Rechner-Ereignis-Maschinendiagramm

Bild
2. Zählen Sie den Rechner der Miley-Moore-Automatenklasse

Für ein Modell ähnlich einem Automaten in Fig. 2 meinen wir mit Eingabe / Ausgabe-Aktionen Prädikate und Aktionen, die Programmfunktionsmethoden von [Automaten] -Klassen sind. Prädikate analysieren den aktuellen Status von Speicherelementen (Variablen, Klasseneigenschaften) in keiner Weise (dies ist wichtig!). Sie haben keine Auswirkungen darauf, geben jedoch abhängig von ihrem Wert einen Booleschen Wert zurück. Aktionen eines Wertes werden nicht zurückgegeben, sondern ändern Speicherelemente.
Aus Abb. 2 Daraus folgt, dass das Rechnermodell wie die „Black Box“ vier Eingangskanäle und sieben Ausgangskanäle in Bezug auf die Anzahl der Prädikate und Aktionen aufweist. Es ist leicht zu erkennen, dass im Vergleich zu einem abstrakten Automaten, der per Definition nicht mehr als einen Eingangs- und einen Ausgangskanal hat, ein struktureller Automat mit vielen Kanälen universeller, flexibler und praktischer ist.

Das Modell in Abb. 2 kann durch „Kleben“ der Zustände 1 und 2 vereinfacht werden. Dazu müssen Sie zuerst den Originalautomaten in einen mehligen Automaten verwandeln. Wir erhalten es durch Laden der Bögen, die in den Zustand der Signale eintreten, mit den Signalen, die durch die Signale der Eckpunkte des Moore-Automaten dargestellt werden. Danach wird der Klebevorgang ersichtlich. Das Ergebnis der Verklebung von Zuständen zu Zustand 2, der nun anfänglich wird, ist in Fig. 2 gezeigt. 3.

Bild
3. Das Ergebnis der Transformation und Verklebung der Zustände des Automaten in Fig. 2

Erläutern Sie die Aktion y1 und die Variable nTypeButtons. Insgesamt implementieren sie ein Protokoll, das Ereignisse simuliert. Die Variable nTypeButtons bestimmt die Art der Eingabesymbole des Automaten, indem sie in digitale Symbole, Operationssymbole, das Symbol "Zurücksetzen" und das Symbol "Gleich" unterteilt wird. Sein Wert gleich Null bedeutet das Fehlen von Eingabezeichen (keine der Rechnertasten wird gedrückt). Nach der Bearbeitung des Symbols bedeutet dies auch, dass das Eingabesymbol automatisch wahrgenommen wird. Dies blockiert die Antwort auf das eingegebene Zeichen.

Der Code für die Klasse des Rechners, der im Rahmen der automatischen visuellen Komponentenprogrammierung (VKPa) [5] erstellt wurde, ist in den Auflistungen 1, 2 aufgeführt.

Listing 1. Header der FCalculator-Klasse
#include "lfsaappl.h" enum Buttons { digit0 = 0, digit1, digit2, digit3, digit4, digit5, digit6, digit7, digit8, digit9, opPlus, opMinus, opCancel, opEqual, opNone }; class FCalculator : public LFsaAppl { public: void MooreAction(); LFsaAppl* Create(CVarFSA *pCVF) { Q_UNUSED(pCVF)return new FCalculator(pTAppCore, nameFsa, pCVarFsaLibrary); } FCalculator(TAppCore *pInfo, string strNam, CVarFsaLibrary *pCVFL); virtual ~FCalculator(void); public: void digitButtonPressed(int button); void operationButtonPressed(int button); private: void s1Entered(); void s2Entered(); void s3Entered(); void s3Exited(); void s5Entered(); void s5Exited(); private: int Rf, Rb; Buttons transitionButton, Op; int nTypeButtons; // 0 - none; 1 - digit button; 2 - operation button; void doOp(Buttons op); protected: int x1(); int x2(); int x3(); int x4(); void y1(); void y3(); void y5(); void y6(); void y7(); void y8(); void y9(); void y10(); int nState{2}; }; 



Lassen Sie uns erklären. In VKPa erbt jede Automatenklasse die Eigenschaften der Basisautomatenklasse LFsaAppl. Die Methode Create () erstellt Kopien der Klassen, die in den dynamischen Bibliotheken automatischer Prozesse enthalten sind. Die virtuelle MooreAction () -Methode überlappt sich, wenn ein Moore-Automatenmodell ausgewählt wird, und definiert Aktionen, die den Zuständen des Automaten zugeordnet sind. Die Methoden x [n] und y [n] sind die Prädikate und Aktionen, die den Eingabe- / Ausgabekanälen des Automaten zugeordnet sind. Der Verhaltensalgorithmus der Klasse [automaton] wird durch die Übergangstabelle (siehe Listing 2) dargestellt, die aus einem Array von Zeichenfolgen vom Typ LArc besteht. Der Rest des Codes wiederholt den Code der Quellklasse Calculator.

Listing 2. Implementierung der FCalculator-Klasse
 #include "stdafx.h" #include "FCalculator.h" #include "DlgCalculator.h" #include "ui_cdlgcalculator.h" static LArc TBL_Calculator[] = { //* LArc("1", "2","x1", "y1"), // [0-9] LArc("2", "1","x3", "y1"), // [c] LArc("2", "2","x1", "y1"), // [0-9] LArc("2", "3","x2", "y1"), // [+][-] LArc("3", "1","x3", "y3"), // [c] LArc("3", "3","x2", "y3"), // [+][-] LArc("3", "4","x1", "y3"), // [0-9] LArc("3", "5","x4", "y3"), // [=] LArc("4", "1","x3", "y1"), // [c] LArc("4", "3","x2", "y1"), // [+][-] LArc("4", "4","x1", "y1"), // [0-9] LArc("4", "5","x4", "y1"), // [=] LArc("5", "1","x3", "y5"), // [c] LArc("5", "2","x1", "y5"), // [0-9] LArc("5", "3","x2", "y5"), // [+][-] //*/ /* LArc("2", "2","x1", "y1y7"), // [0-9] LArc("2", "2","x3", "y1y6"), // [c] LArc("2", "3","x2", "y1y8"), // [+][-] LArc("3", "2","x3", "y3y6"), // [c] LArc("3", "3","x2", "y3y8"), // [+][-] LArc("3", "4","x1", "y3y7"), // [0-9] LArc("3", "5","x4", "y3y9"), // [=] LArc("4", "2","x3", "y1y6"), // [c] LArc("4", "3","x2", "y1y8"), // [+][-] LArc("4", "4","x1", "y1y7"), // [0-9] LArc("4", "5","x4", "y1y9"), // [=] LArc("5", "2","x3", "y5y6"), // [c] LArc("5", "2","x1", "y5y7"), // [0-9] LArc("5", "3","x2", "y5y8"), // [+][-] */ // LArc("1", "1","--", "y10"), // SWITCH LArc() }; FCalculator::FCalculator(TAppCore *pInfo, string strNam, CVarFsaLibrary *pCVFL): LFsaAppl(TBL_Calculator, strNam, nullptr, pCVFL) { pTAppCore = pInfo; Rf= 0; Rb = 0; Op = opNone; } FCalculator::~FCalculator(void) { } //   int FCalculator::x1() { if (nTypeButtons != 1) return false; else return true; } //   +, - int FCalculator::x2() { if (nTypeButtons == 0 || nTypeButtons != 2) return false; if (transitionButton != opCancel && transitionButton != opEqual ) return true; else return false; } //  Cancel int FCalculator::x3() { if (nTypeButtons == 0 || nTypeButtons != 2) return false; if (transitionButton == opCancel) return true; else return false; } //  opEqual int FCalculator::x4() { if (nTypeButtons == 0 || nTypeButtons != 2) return false; if (transitionButton == opEqual) return true; else return false; } void FCalculator::y1() { nTypeButtons = 0; } void FCalculator::y3() { s3Exited(); } void FCalculator::y5() { s5Exited(); } void FCalculator::y6() { s1Entered(); } // 1 void FCalculator::y7() { s2Entered(); } // 2, 4 void FCalculator::y8() { s3Entered(); } // 3 void FCalculator::y9() { s5Entered(); } // 5 void FCalculator::y10() { switch(nState) { case 2: if (x1()) { y1();y7(); } if (x3()) { y1();y6(); } if (x2()) { y1();y8(); nState = 3; } break; case 3: if (x3()) { y3();y6(); nState = 2; } if (x2()) { y3();y8(); } if (x1()) { y3();y7(); nState = 4; } if (x4()) { y3();y9(); nState = 5; } break; case 4: if (x3()) { y1();y6(); nState = 2; } if (x2()) { y1();y8(); nState = 3; } if (x1()) { y1();y7(); } if (x4()) { y1();y9(); nState = 5; } break; case 5: if (x3()) { y5();y6(); nState = 2; } if (x1()) { y5();y7(); nState = 2; } if (x2()) { y5();y8(); nState = 3; } break; } } void FCalculator::MooreAction() { // return; string strState = FGetState(); if (strState=="1") { y6(); } else if (strState=="2") { y7(); } else if (strState=="3") { y8(); } else if (strState=="4") { y7(); } else if (strState=="5") { y9(); } } /////////////////////////////////////////////////////////////////////////// void FCalculator::digitButtonPressed(int button) { transitionButton = static_cast<Buttons>(button); nTypeButtons = 1; } void FCalculator::operationButtonPressed(int button) { transitionButton = static_cast<Buttons>(button); nTypeButtons = 2; } void FCalculator::s1Entered() { Rf = 0; Rb = 0; Op = opNone; static_cast<CDlgCalculator*>(this->pCVarFSA->pVFsaDialog)->ui->lcdNumber->display(Rf); } void FCalculator::s2Entered() { if (Rf < 9999999) { Rf = Rf*10 + transitionButton; static_cast<CDlgCalculator*>(this->pCVarFSA->pVFsaDialog)->ui->lcdNumber->display(Rf); } } void FCalculator::s3Entered() { if (Rb != 0) { doOp(Op); static_cast<CDlgCalculator*>(this->pCVarFSA->pVFsaDialog)->ui->lcdNumber->display(Rf); } Rb = Rf; Op = transitionButton; } void FCalculator::s3Exited() { nTypeButtons = 0; if (transitionButton > digit9 && transitionButton < opCancel ) { doOp(transitionButton); Rb = 0; Op = transitionButton; static_cast<CDlgCalculator*>(this->pCVarFSA->pVFsaDialog)->ui->lcdNumber->display(Rf); } else { Rf = 0; } } void FCalculator::s5Entered() { doOp(Op); Op = opNone; Rb = Rf; // added by me static_cast<CDlgCalculator*>(this->pCVarFSA->pVFsaDialog)->ui->lcdNumber->display(Rf); } void FCalculator::s5Exited() { nTypeButtons = 0; if (transitionButton <= 9) { Rb = 0; Rf = 0; } } void FCalculator::doOp(Buttons op) { switch (op) { case opPlus: Rf = Rf + Rb; break; case opMinus: Rf = Rb - Rf; break; default: break; } } 



Hinweis Listing 2 enthält drei Sprungtabellen (zwei sind auskommentiert). Auf diese Weise werden die Funktionen der dedizierten Steuerung realisiert, wenn das Verhalten der Klasse nach dem Entfernen des Kommentars "per Mausklick" geändert werden kann, ohne die Methoden und Eigenschaften zu beeinträchtigen. Für die Modellierung der SWITCH-Technologie (Details siehe [9]) im Rahmen der VKPA-Technologie wurden die y10-Methode und die entsprechende Zeile in der Übergangstabelle (siehe die mit dem Kommentar SWICH gekennzeichnete Zeile) eingeführt. In diesem Fall wird das Verhalten eines Automaten durch einen zyklischen Aufruf an den SWITCH-Operator modelliert, der das Verhalten des Automaten imitiert (hier fungiert der VKPa-Automat als externe Umgebung).

3.2. Passives Rechnermodell


Das aktive Rechnermodell durchsucht ständig die Eingangskanäle. Sobald der Wert der Variablen nTypeButtons ungleich Null wird, dient dies als Zeichen für das Eintreffen des nächsten Symbols am Eingang des Automaten. Infolgedessen werden der Übergang und die Aktion y1 ausgelöst, wodurch die Variable nTypeButtons zurückgesetzt wird und die automatische Maschinenwiederauslösung durch dasselbe Zeichen blockiert wird.
Im Gegensatz zum Modell des „aktiven Rechners“ kann ein Ereignisautomat per Definition kein Eingabesymbol erneut verarbeiten. Jetzt ist klar, dass "die größten Schwierigkeiten bei der Verwendung des Automatenansatzes ... in Ereignissystemen" darin zu bestehen scheinen, die Aktivität eines aktiven Automaten zu unterdrücken und seine Funktion mit Ereignissen zu verknüpfen. Wir zeigen am Beispiel des soeben erstellten „aktiven Rechners“ die Vorgehensweise zum Umschalten auf einen passiven Automaten.
Die VKPa-Umgebung enthält eine schrittweise Anleitung zum Debuggen automatischer Prozesse. Es kann jedoch zur Simulation von Ereignismaschinen verwendet werden. Dazu 1) stellen Sie den Automatenraum, in den der Automat gestellt wird, schrittweise ein (beachten Sie, dass es sich nicht um einen separaten Automaten handelt, sondern um den gesamten Automatenraum, der Automaten enthält), und 2) beziehen Sie die Zeitpunkte des Auftretens von Ereignissen auf die Ausführung eines einzelnen Schrittes der Operation des Raums. Listing 3 zeigt, wie dies getan wird. Es werden nur die am Modell vorgenommenen Änderungen wiedergegeben (der Klassenheader bleibt unverändert).

Listing 3. Eine mögliche Variante der FCalculator-Klasse
 static LArc TBL_Calculator[] = { LArc("st", "st","^x12", "y12"), // LArc("st", "1","x12", "y11"), // // ... }; ... //   bool FCalculator::FCreationOfLinksForVariables() { pNet = GetPointerToNet(); //    if (pNet) { string str = pNet->strName; //    //  -  pSV = this->pTAppCore->pSetVarSetting->GetAddressVar(const_cast<char*>(str.c_str())); } return true; } ... // int FCalculator::x12() { if (!pNet) return false; if (!pSV) return false; return true; } ... //    step-by-step void FCalculator::y11() { pSV->bIfStepByStep = true; } //   void FCalculator::y12() { FCreationOfLinksForVariables(); } // ... ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void FCalculator::digitButtonPressed(int button) { ... pSV->bIfStopAllTasks = false; //     } void FCalculator::operationButtonPressed(int button) { ... pSV->bIfStopAllTasks = false; //     } ... 



Hier wird zunächst ein zusätzlicher [Ausgangs] -Zustand eingeführt, in dem ein Verweis auf den Raum, in dem sich die Maschine befindet, und eine Verknüpfung zu einem Objekt, das die Eigenschaften des Raums (einschließlich seines Betriebsmodus) definiert, überprüft werden. Eh bildet die Handlung von y12. Wenn die Verknüpfungen gesetzt sind, erfolgt ein Übergang in den [früheren] Ausgangszustand des Rechnermodells mit der Installation einer schrittweisen Betriebsart des Automatenraums.

Ferner arbeitet das Modell in einer schrittweisen Weltraumbetriebsart. Der Start eines Schritts implementiert den Code, der in die Ereignishandler für die Eingabe des nächsten Zeichens eingefügt wurde (siehe Listing 3 für die Änderungen an den Methoden digitButtonPressed und operationButtonPressed).

4. Warum?


Warum etwas erfinden, wenn es, wie anzunehmen ist, ein fortgeschritteneres Ereignismodell von D. Harel gibt. Und wie man anders denkt, wenn es in UML, Stateflow, in der Qt-Bibliothek usw. ausgeführt wurde. usw. und es gibt nicht viel Panik über seine Mängel. Nun, sie nannten die Signale Ereignisse und verwandelten die aktive Maschine in eine passive ... Und wenn das Modell, wie sie sagen, auch formal den klassischen Mili / Moore-Maschinen entspricht, wie kann man dann nicht daran glauben? Und so ist es, wenn all diese Aussagen nur auf den Glauben bezogen sind ...

Nehmen Sie für den Beginn der Veranstaltung (das ist genau das, was wir oben gemacht haben). Ein klassischer Strukturautomat hat zum Beispiel viele Eingangskanäle, von denen jeder einem Signal zugeordnet ist, und sie können gleichzeitig / parallel verarbeitet werden. Laut UML kann "jedes Objekt nur ein Ereignis gleichzeitig verarbeiten", und selbst wenn zwei Ereignisse gleichzeitig auftreten, verarbeitet das Objekt sie immer noch nacheinander "[10]. Auf der Definitionsebene sind Signale und Ereignisse also gleichwertig, aber die Idylle bricht bei der Implementierung von Modellübergängen zusammen.

Betrachten Sie das Beispiel, mit dem ich anfange, eine Sprache oder Technologie zu testen / zu lernen. Es geht um die Software-Implementierung des Elementmodells AND-NOT. Auf der strukturellen Ebene entspricht es der „Black Box“, die zwei Eingangskanäle und einen Ausgang hat, und auf der algorithmischen Ebene dem in Abb. 4.

Bild
Abb. 4. Das Automatenmodell des Elements AND NOT

Es ist verständlich, wie man ein reguläres Vorgehensmodell erstellt (siehe Listing 4) oder wie man einen Automaten in VKPa implementiert (siehe Listing 5), aber wie man dies anhand des Ereignisautomaten der Qt-Bibliothek wiederholt, ist aufgrund des Problems der Implementierung des Übergangs vom Zustand „1“ nicht sehr klar. auf "0" setzen, was die gleichzeitige Analyse mehrerer Ereignisse erfordert.

Listing 4. Objektimplementierung des AND-NOT-Vorgehensmodells

Listing 4. Objektimplementierung des AND-NOT-Vorgehensmodells
 class INE { public: INE() {} ~INE(void); bool bX1, bX2, bY; bool f() { return bY = !(bX1&&bX2); } }; 




Listing 5. Objektimplementierung des AND-NOT-Automatenmodells
 LArc T_INE[] = { LArc("s1", "s0", "x1x2", "y1"), LArc("s0", "s1", "^x1", "y2"), LArc("s0", "s1", "^x2", "y2"), }; class Ine : public LFsaAppl { public: Ine(string strNam = "-"): LFsaAppl(T_INE, strNam) {} ~Ine(void); bool bX1, bX2; protected: int x1() { return bX1; } int x2() { return bX2; } }; 


So sei die Implementierung des Ereignismodells des NAND-Elements im Rahmen der Qt-Automatenklassen „Hausaufgabe“ für die Habrovaner. Ich kann ihre Entscheidung in Stateflow nur als „Kirsche auf dem Kuchen“ bezeichnen. Es ist in Abb. 2 dargestellt. 5. Hier wird das Stateflow-Relief verwendet, mit dem der Übergang nicht mit einem Ereignis markiert werden kann: Wenn der Ereignisname nicht angegeben wird, erfolgt der Übergang, wenn ein Ereignis eintritt (ein Beispiel finden Sie in der Übergangsbezeichnung in [13]).

Bild
Abb. 5. Ein Automatenmodell eines AND-NOT-Elements in Stateflow

Zustandsmaschinen sind also ein hybrides (Aktiv-Passiv-) Modell einer Maschine. Es ist zwar nicht klar, wie sich die Maschine verhält, wenn überhaupt keine Ereignisse eintreten. Es ist davon auszugehen, dass es in Erwartung von Ereignissen „einfriert“. Und wenn nicht? Das heißt Am Ende ist es wahrscheinlich eher ein passives als ein aktives Maschinenmodell. Obwohl nur im Aussehen, ist es schwierig, sich von letzteren zu unterscheiden.

5. Fazit


In Bezug auf Ereignisse kann man sagen, dass die Implementierung des klassischen Automatenmodells aufgrund der Aktivität dem Modell synchroner Automaten vorzuziehen ist. Wenn wir allgemein von automatischer Programmierung sprechen, zeigt das Stateflow-Erweiterungspaket, was für eine völlig andere Art der Programmierung sein kann. Aber leider bisher nur perspektivisch, weil Probleme bleiben aufgrund des Stateflow-Rechenmodells, das im Wesentlichen ein Blockdiagramm bleibt. Genau aus diesen Gründen wird die visuelle Programmierung in Statefow zusammen mit den Automaten durch die Notation von Flussdiagrammen dargestellt.

Herauszufinden, wo die echte automatische Programmierung ist und wo ihre Nachahmung ist, ist eines unserer Hauptziele. Im vorigen Artikel [5] haben wir eine der grundlegenden Aufgaben gelöst - wir haben das Konzept der Automatenprogramme formuliert. Als nächstes müssen Sie sich mit der Definition eines Programmverwaltungsmodells befassen, das endlich automatisiert und für Programmierer effektiv und bequem sein sollte.

Nachdem wir uns mit den Ereignissen befasst hatten, legten wir den Grundstein für diese Arbeit. In weiteren Artikeln werden wir bereits die Details des von D. Harel vorgeschlagenen Modells verstehen. Wir sagen, dass sie, wenn sie ein wenig voraus läuft, das Verständnis von Automaten verzerrt hat. Auf der anderen Seite hat sie Probleme aufgedeckt, die es ohne sie nicht erlauben würden, eine effektive automatische Programmierung im Rahmen des klassischen Modells zu bilden, die Programmierer anziehen würde.

Wir haben oben herausgefunden, dass zumindest auf der Ereignisebene klassische Automaten keine Probleme haben. Wir werden weiter verstehen ... In der Zwischenzeit ist dies nur der Anfang. Wir warten auf viele interessante Dinge und gehen nicht über die klassische Theorie der Automaten hinaus. Dies ist entscheidend, wenn wir eine wirklich automatisierte Programmierung wünschen. Wir wünschen Ihnen viel Erfolg! :)

Referenzliste


1. Borovsky A.N. Qt4.7. Praktische C ++ Programmierung. - SPb .: BHV-Petersburg, 2012 .-- 496 p.
2. Buch G., RAMBO J., Jacobson I. UML. Benutzerhandbuch. Zweite Auflage. Akademiya IT: Moskau, 2007 .-- 493 p.
3. Shalyto A. A. Eine neue Vorlesung über automatische Programmierung. 2019, [Elektronische Ressource], Zugriffsmodus: www.youtube.com/watch?v=PPWTxceMutk&feature=youtu.be , kostenlos. Yaz. Russisch (Datum der Behandlung 5. Dezember 2019).
4. Stateflow. www.mathworks.com/products/stateflow.html , kostenlos. Yaz. Englisch (Ausgabetag 7.01.2020).
5. Turing-Maschine als Modell von Automatenprogrammen. habr.com/de/post/481998 , kostenlos. Yaz. Russisch (Ausgabetag 7.01.2020).
6. Melikhov A.N. Orientierte Graphen und Zustandsautomaten. - M .: Nauka, 1971. - 416 p.
7. KUDRYAVTSEV VB, Aleshin S.V., PODKOLZIN A.S. Einführung in die Theorie der Automaten - M .: Wissenschaft. Ch. ed. Phys.-Math. Lit. 1985 .-- 320 p.
8. Tukkel N. I., Shalyto A.A. Implementierung von Automaten bei der Programmierung von Ereignissystemen. "Programmer", 2002. Nr. 4. C.74-80.
9. Polikarpova N., A. Shalyto A. Automatisierung. 2nd ed., St. Petersburg.: Peter, 2011 .-- 176 p.
10. Rambo J., Jacobson A., Butch G. UML: spezielle Referenz. - St. Petersburg: Peter, 2002 .-- 656 p.
11. Goma H. ​​UML. Entwurf von Echtzeitsystemen, parallelen und verteilten Anwendungen: Per. aus dem Englischen - M .: DMK Press, 2002. - 2002. - 704 p.
12. SHALYTO A.A. SWITCH-Technologie. Algorithmus und Programmierung von Logiksteuerungsaufgaben. St. Petersburg: Nauka, 1998.628 s.
13. Rogachev G.N. Stateflow-Notationen. bourabai.kz/cm/stateflow13.htm , kostenlos. Yaz. Russisch (Datum der Beschwerde 01.10.2020).

Source: https://habr.com/ru/post/de483610/


All Articles