Moore-Automaten mit C#
Nachdem ich eine Weile an einem Synchronisationsproblem bei der Verwendung von seriellen Schnittstellen zur Kommunikation mit Mobiltelefonen gesessen habe, kam mir eine nette Idee: Ich verwende einen endlichen Transduktor! Genauer: Einen Moore-Automaten. Zur Erklaerung: Ein endlicher Automat laesst sich durch einen Graphen veranschaulichen. Ein Knoten ist ein Zustand . Nur ein Zustand kann zu einem Zeitpunkt angenommen werden, wobei Zeit eigentlich keine Rolle spielt. Befindet sich der Automat im Zustand
und erhaelt er ein Eingabezeichen
(Woerter, Symbole, Nachrichten, o.ae.) und es ist ein Zustandsuebergang
durch eine Funktion
definiert, dann geht der Automat in den neuen Zustand
ueber.
Mit genau solch einem Automaten kann ich das Synchronisationproblem loesen. Mehr zum Problem: Die Verbindung ueber den COM Port ist nie still. Das Mobiltelefon sendet andauernd Statusmeldungen. Wenn ich eine Anweisung sende, dann liegt diese Anweisung auch noch eine Weile im Puffer, sodass meine eigene Anweisung als Rueckgabe gelesen wird. Nun kann ich mit Hilfe des Automaten genau festlegen, wann eine Statusmeldung und sonstige ungewollte Nachrichten ignoriert werden und wann nicht. Pretty cool.
Ich will den Code natuerlich niemanden vorenthalten… Die Ausgabe meines Testprogramms sieht wie folgt aus:
Checking State 1 with ABC... Found Checking State 1 with XYZ... Not found Checking State 1 with 123... Not found Checking State 2 with ABC... Not found Checking State 2 with XYZ... Found Checking State 2 with 123... Not found Checking State 3 with ABC... Not found Checking State 3 with XYZ... Not found Checking State 3 with 123... Found This Moore-Machine is a partially-specified deterministic finite state machine. Following transitions are missing: (State 1, "XYZ") -> undefined (State 1, "123") -> undefined (State 2, "ABC") -> undefined (State 2, "123") -> undefined (State 3, "ABC") -> undefined (State 3, "XYZ") -> undefined State 1 is running... Got input: XYZ State 1 is running... Got input: ABC State 2 is running... Got input: 123 State 2 is running... Got input: XYZ State 3 is running... Got input: ABC State 3 is running... Got input: 123 State 1 is running... Got input: XYZ
Und die Testumgebung, die das produziert, sieht so aus:
using System; using System.Threading; namespace visusNET.FiniteStateMachine { public class Test { [STAThread] public static void Main() { string[] sigma = new string[] { "ABC", "XYZ", "123" }; State state1 = new State(State1, "State 1"); State state2 = new State(State2, "State 2"); State state3 = new State(State3, "State 3"); State[] S = { state1, state2, state3 }; TransitionFunction delta = new TransitionFunction(); delta.AddTransition(state1, sigma[0], state2); // state1 --ABC--> state2 delta.AddTransition(state2, sigma[1], state3); // state2 --XYZ--> state3 delta.AddTransition(state3, sigma[2], state1); // state3 --123--> state1 MooreMachine machine = new MooreMachine(sigma, S, state1, delta); machine.Delay = 1000; machine.Interval = 5000; machine.Analyze(); Thread machineThread = new Thread(new ThreadStart(machine.Run)); machineThread.Start(); while (true) { machine.SetInput("ABC"); Thread.Sleep(1000); machine.SetInput("XYZ"); Thread.Sleep(1000); machine.SetInput("123"); Thread.Sleep(1000); } } public static void State1() { Console.WriteLine("State 1 is running..."); } public static void State2() { Console.WriteLine("State 2 is running..."); } public static void State3() { Console.WriteLine("State 3 is running..."); } } }
Die Dateien dazu gibt es hier: FiniteStateMachine.zip.







am 14. November 2009 um 22:05 Uhr.
thanks for moore machine’s example. very nice;)
am 14. November 2009 um 22:09 Uhr.
There is also an english version of this post on CodeProject: http://www.codeproject.com/KB/recipes/MooreMachine.aspx