Qualifikationsphase 2
Es wird ein Programm gesucht, das als endlicher Automat arbeiten kann. Da sich die endlichen Automaten nur in Details unterscheiden, kann das gesuchte Programm als Vorlage für alle Simulationen endlicher Automaten dienen. Der Programmcode ist für alle Verfahren ähnlich. Unter Type muss tZustand den entsprechenden Verhältnissen angepasst werden. Die Überführungsfunktion muss an das Eingabealphabet und die Zustände, die Ausgabefunktion an das Ausgabealphabet angeglichen werden.
Das Grundgerüst könnte wie folgt aussehen:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
StdCtrls;
type
{ TMain }
TZustand=(......);// Zustände eingeben
TMain = class(TForm)
BtReset: TButton;
BtTakt: TButton;
BtEnde: TButton;
EdEingabe: TEdit;
EdAusgabe: TEdit;
LbEingabe: TLabel;
LbAusgabe: TLabel;
procedure BtEndeClick(Sender: TObject);
procedure BtResetClick(Sender: TObject);
procedure BtTaktClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
zustand:TZustand;
pos: integer;
function u(s: tZustand; e: char): tZustand;
function g(s: tZustand; e: char): string;
public
{ public declarations }
end;
var
Main: TMain;
implementation
{$R *.lfm}
{ TMain }
function TMain.u(s: tZustand; e: char): tZustand;
begin
case s of
s0: case e of
'?': u:= ...;
// Zustände eingeben
'?': u:= ...;
end;
......
end;
end;
function TMain.g(s: tZustand; e: char): string;
begin
case s of
s0: case e of
'?': g:= '...';
end;
......
end;
end;
procedure TMain.BtEndeClick(Sender: TObject);
begin
close;
end;
procedure TMain.BtResetClick(Sender: TObject);
begin
pos:=0;
zustand:=s0;
EdAusgabe.Text:='';
end;
procedure TMain.BtTaktClick(Sender: TObject);
var eingabe, ausgabe, automat:string;
e: char;
begin
eingabe:=uppercase(EdEingabe.Text);
ausgabe:=uppercase(EdAusgabe.Text);
if pos<length(eingabe) then
begin
pos:=pos+1;
e:=eingabe[pos];
automat:=uppercase(g(zustand,e));
zustand := u(zustand,e);
ausgabe:=ausgabe + automat;
EdAusgabe.Text := ausgabe;
end
end;
procedure TMain.FormCreate(Sender: TObject);
begin
pos:=0;
zustand:=S0;
end;
end.
Beispiel: SOS

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics,
Dialogs,
StdCtrls;
type
{ TForm1 }
tZustand = (S0,SW,S1,S2,S3,S4,S5,S6,S7,S8,S9,SE);
TForm1 = class(TForm)
BtReset: TButton;
BtEinzel: TButton;
BtDauer: TButton;
EdEingabe: TEdit;
EdAusgabe: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure BtResetClick(Sender: TObject);
procedure BtEinzelClick(Sender: TObject);
procedure BtDauerClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
zustand: tZustand;
pos: integer;
function u(s: tZustand; e: char): tZustand;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
procedure TForm1.BtResetClick(Sender: TObject);
begin
pos := 0 ;
zustand := s0;
EdAusgabe.Text := '';
end;
procedure TForm1.BtEinzelClick(Sender: TObject);
var eingabe,ausgabe: string;
e: char;
begin
eingabe := upperCase(EdEingabe.text);
ausgabe := EdAusgabe.text;
if (pos < length(eingabe)) then
begin
pos:=pos+1;
e:=eingabe[pos];
if e in ['.','-','w','W'] then
begin
zustand := u(zustand,e);
if zustand = se then ausgabe := 'SOS!SOS!SOS!';
EdAusgabe.Text := ausgabe;
end
end
end;
procedure TForm1.BtDauerClick(Sender: TObject);
var i:integer;
begin
for i:=1 to length(EdEingabe.text) do BtEinzelClick(sender);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
pos:=0;
zustand:=S0;
end;
function TForm1.u(s: tZustand; e: char): tZustand;
begin
case s of
S0: case e of
'.' : result := S0;
'-' : result := S0;
'W','w': result := SW;
end;
SW: case e of
'.' : result := S1;
'-' : result := S0;
'W','w': result := SW;
end;
S1: case e of
'.' : result := S2;
'-' : result := S0;
'W','w': result := SW;
end;
S2: case e of
'.' : result := S3;
'-' : result := S0;
'W','w': result := SW;
end;
S3: case e of
'.' : result := S0;
'-' : result := S4;
'W','w': result := SW;
end;
S4: case e of
'.' : result := S0;
'-' : result := S5;
'W','w': result := SW;
end;
S5: case e of
'.' : result := S0;
'-' : result := S6;
'W','w': result := SW;
end;
S6: case e of
'.' : result := S7;
'-' : result := S0;
'W','w': result := SW;
end;
S7: case e of
'.' : result := S8;
'-' : result := S0;
'W','w': result := SW;
end;
S8: case e of
'.' : result := S9;
'-' : result := S0;
'W','w': result := SW;
end;
S9: case e of
'.' : result := S0;
'-' : result := S0;
'W','w': result := SE;
end;
end
end;
initialization
{$I unit1.lrs}
end.
Beispiel: Er, Sie. Es

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics,
Dialogs,
StdCtrls;
type
{ TForm1 }
tZustand = (S0,S1,S2,S3,SER,SES,SSIE);
TForm1 = class(TForm)
BtReset: TButton;
BtEinzel: TButton;
BtDauer: TButton;
EdEingabe: TEdit;
EdAusgabe: TEdit;
Label1: TLabel;
Label2: TLabel;
procedure BtResetClick(Sender: TObject);
procedure BtEinzelClick(Sender: TObject);
procedure BtDauerClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
zustand: tZustand;
pos: integer;
function u(s: tZustand; e: char): tZustand;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
procedure TForm1.BtResetClick(Sender: TObject);
begin
pos := 0 ;
zustand := s0;
EdAusgabe.Text := '';
end;
procedure TForm1.BtEinzelClick(Sender: TObject);
var eingabe,ausgabe: string;
e: char;
begin
eingabe := upperCase(EdEingabe.text);
ausgabe := EdAusgabe.text;
if (pos < length(eingabe)) then
begin
pos := pos + 1;
e := eingabe[pos];
if e in ['E','I','R','S'] then
begin
zustand := u(zustand,e);
case zustand of
SER: ausgabe := ausgabe + 'ER, ';
SES: ausgabe := ausgabe + 'ES, ';
SSIE: ausgabe := ausgabe + 'SIE, ';
end;
EdAusgabe.Text := ausgabe;
end
end
end;
procedure TForm1.BtDauerClick(Sender: TObject);
var i:integer;
begin
for i:=1 to length(EdEingabe.text) do BtEinzelClick(sender);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
pos:=0;
zustand:=S0;
end;
function TForm1.u(s: tZustand; e: char): tZustand;
begin
case s of
S0: case e of
'E': result := S1;
'I': result := S0;
'R': result := S0;
'S': result := S2;
end;
S1: case e of
'E': result := S1;
'I': result := S0;
'R': result := SER;
'S': result := SES;
end;
S2: case e of
'E': result := S1;
'I': result := S3;
'R': result := S0;
'S': result := S2;
end;
S3: case e of
'E': result := SSIE;
'I': result := S0;
'R': result := S0;
'S': result := S2;
end;
SER: case e of
'E': result := S1;
'I': result := S0;
'R': result := S0;
'S': result := S2;
end;
SES: case e of
'E': result := S1;
'I': result := S3;
'R': result := S0;
'S': result := S2;
end;
SSIE: case e of
'E': result := S1;
'I': result := S0;
'R': result := SER;
'S': result := SES;
end;
end
end;
initialization
{$I unit1.lrs}
end.
Wie schon erwähnt, ist es ziemlich lästig, für jeden neuen Automaten ein neues Programm zuschreiben. WIe aus den Programmen zu ersehen ist, unterscheiden sie sich eigentlich nur in der Anzahl der Zustände und den verschedenen Übergängen und Ausgaben.