Automata Toolbox - Outline


Inhalt

Module für die gängigen (nichtdeterministischen) sequentiellen Automaten (Turingmaschine, endlicher Automat, Kellerautomat), mit Varianten.

Simulator, der zu gegebenem Automaten und Eingabe alle akzeptierenden Rechungen (durch Breitensuche im Berechnungsbaum) sucht.

Geplant: während der Simulation werden logische Formeln getestet, die den (gewünschten) Programmzustand beschreiben.


Anwendung: Test von Automaten

Die typischen Übungsaufgaben "Schreiben Sie einen Kellerautomaten für die Sprache soundso" kann man damit automatisch korrigieren.

Der Student schickt seinen Automaten als Haskell-Quelltext an einen Mailserver (procmail), der bei mir (isun11) läuft. Dieser linkt das eingesandte Modul zum Simulatorprogramm, und führt die vorgesehenen Tests aus. Das Resultat wird vom Server an mich und auch an den Studenten geschickt. Von mir aus kann der Student markieren, ob ich das Resultat sehen soll (falls er erst probieren will).

Bei der Aufgabenstellung beachten: gleich die passenden Invarianten mit angeben, also "Schreiben Sie einen Automaten, der genau die Sprache soundso akzeptiert, und bei dem in jeder Konfiguration links vom Kopf stets doppelt soviele Einsen wie ..."


Nebenwirkung: Bekanntschaft mit Haskell

Weil es mathematisch am saubersten, und auc für mich am bequemsten ist, schreibe ich die Programme in Haskell. Der Student ist dazu auch gezwungen (sein Modul wird ja zusammen mit meinen kompiliert) aber die Sache ist so organisiert, daß er dazu die Sprache Haskell nicht kennen muß. Beispiel
module TuringExample
where
import Turing

ex = Machine
    { start = "q0"
    , final = mkSet [ "q2" ]
    , transitions = turing $ listToFM
          [ (("q0", ' '), [ ("q1", 'X', R) ])
          , (("q1", ' '), [ ("q2", 'Y', R) ])
          ]
    }
Das versteht nach kurzem Draufgucken jeder.

Natürlich legt das Verfahren dem Studenten nahe, sich dochmal mit Haskell zu beschäftigen, zum Beispiel, wenn er seine Automaten selbst simulieren will (und nicht zu meinem Mailserver schicken).


Strukturelle Betrachtung von Automaten

Simulatoren für dieses und jenes gibt es wie Sand am Meer. Warum noch ein neues Projekt? Weil ich strukturelle Gemeinsamkeiten der Automatenmodelle ganz explizit sichtbar machen will. Die Programme sollen möglichst generisch sein, so daß man viele viele Sachen leicht ändern (orthogonal kombinieren) kann.

Beispiele: Eine Turingmaschine mit einem Band ist Standard.

Wenn der Kopf nur nach rechts fährt (und nichts schreibt), dann ist es ein endlicher Automat.

Nun darf der Kopf beliebig fahren, aber nie schreiben. Dann können immer noch nur reguläre Sprachen akzeptiert werden (Satz von Büchi über Transducer, oder so ähnlich). Ich möchte einen Typkonstruktor "Readonly", den man auf einen Automatentyp anwendet, und dann ohne weitere Programmänderungen nur nicht schreibende Programme erhält.

Was ist, wenn der Kopf beim Rechtsfahren schreiben darf. aber beim Linksfahren löschen muß? Dann haben wir einen Keller.

Wir können uns statt Band auch ein Gitter oder einen Baum oder irgendeinen Graphen denken. Es ist einfach eine Speicherstruktur, und wir müssen uns für jeden Zustand den Speicherinhalt, Kopfposition und Zustand merken. Der Automatentyp wird also mit dem Speicher- (und Index-)Typ parametrisiert.

Man kann dann Aufgaben stellen wie "Schreibe einen Automaten, der erkennt, ob ein Graph einen Kreis enthält". oder "zusammenhängend ist". oder "ob ein Baum vollständig (d. h. alle Blätter gleich tief) ist".

Eine interessante Sache in dieser Richtung sind Automaten mit Pebbles: wie ein normaler read-only-Automat auf irgendeiner Struktur, der aber zusätzlich eine Markierung (Pebble) in der Struktur ablegen darf (und in jedem Zustand fragen, ob auf der aktuellen Position sich eine Markierung befindet). Das entspricht einem Typkonstruktor "Pebble", der zu einem beliebigen Automaten die Pebble-Verwaltung hinzufügt.

Es gibt noch andere Arten der Automatentyp-Kombination: Ich möchte durch wenige Worte aus zwei Einbandmaschinen eine Zweibandmaschine bauen. Typische Anwendung: auf dem einen Band ein nur-rechts-Automat (siehe oben), auf dem anderen ein Keller (siehe oben). Zusammen ergibt das den üblichen Kellerautomaten.


Operationen mit Automaten

Man kann die aus der Grundvorlesung bekannten Automatenoperationen (Boolesche, Verkettung, Stern, Homomorphismen) implementieren (oder implementieren lassen) und den Studenten zeigen. Durch die referentielle Transparenz von Haskell erhoffe ich mir davon eine sehr hohe Lesbarkeit.

Funktionales Programmieren

Die Automatenmodule kann ich auch als Beispiel für die "Praktische Funktionale Programmierung" nehmen. Die Studenten müßten den Inhalt (Formale Sprachen) schon kennen, und können sich deswegen Gedanken über die Implementierung machen.

Eine wesentliche Eigenschaft sind die stark polymorphen Typen der Funktionen. Ich kann daran Typkonstruktoren und Konstruktorklassen erläutern sowie aktuell diskutierte Erweiterungen des Haskell-Standards (Multi Parameter Type Classes).


Zukunftsmusik

Ich kann mir durchaus einen Grundkurs vorstellen, der im allerersten Semester einerseits Diskrete Mathematik enthält und andererseits praktische Übungen in einer rein funktionalen Sprache. (Das kann man wunderbar verknüpfen!)

(Alles Weitere, sicher ebenfalls Nötige, wie zum Beispiel Analysis oder imperative Sprachen, dann ab zweitem Semester.)

In der Theorie können wir dann die erlernte funktionale Sprache als ausführbare Spezifikation nutzen für die Begriffe a aus den folgenden Vorlesungen (Beispiel Automaten und Sprachen). Dann sieht alles viel praktischer aus, der Student kann die Definitionen und Sätze tatsächlich hinschreiben, der Compiler prüft auf Typkorrektheit, und schließlich kann man alles sogar ausführen!


best viewed with any browser


http://www.informatik.uni-leipzig.de/~joe/ mailto:joe@informatik.uni-leipzig.de