Informatik

Qualifikationsphase 2

PSEA: Programmsimulation für endliche Automaten

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

zjz

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

nhj

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.

V.Berg • Bergisch Gladbach • ImpressumHaftungsausschluss