Dateioperationen

Bei dem Expertensystem wurden Daten als neue Klauseln in das Programm integriert. Um die Daten dauerhaft zu machen, wäre es gut, sie auf einem Medium zu speichern. Allerdings werden neue Klauseln im Rechner in einer Weise abgespeichert, dass sie beim Speichern des Programms verloren gehen. Man muss also die Klauseln getrennt in einer eigenen Datei speichern. Zum Einlesen kann man das Prädikat consult verwenden. Allerdings ist es danach nicht mehr möglich, den Datenbestand im Programm zu erweitern.

Somit müssen neue Klauseln sofort in eine Datei geschrieben werden und zwar so, dass sie später durch andere Programmklauseln wieder eingelesen und mit assert in das Programm integriert werden können. Letzteres erfordert spezielle Maßnahmen, die in anderen Programmiersprachen nicht nötig sind.

Um die entsprechenden Prädikate in ihrer Wirkung vorzustellen, werden wir ein kleines Datenbankprogramm nutzen, das zu einem Namen N zusätzliche Eigenschaften E speichert. In der Fassung ohne Dateisicherung besteht das Programm aus nur zwei Klauseln:

ein(N,E):-assert(dat(N,E)).
aus(N,E):-clause(dat(N,E),true).
Namen N und Eigenschaft E in das Programm eingliedern
Vorgabe N bzw. E suchen, nicht vorgegebene Daten ausgeben

Will man neue Daten eingeben, so geschieht dies z.B. mit dem Aufruf ein('Fiffi','Walddorf, Markt2')..
Um Daten zu suchen, kann man aus('Fiffi',X). eingeben. Ausgegeben wird dann X='Walddorf, Markt2'.

Die Werkzeuge

In Dateien (und auf Geräte) schreiben kann man mit dem Prädikat write, aus ihnen lesen mit read. Man muss allerdings dem Rechner sagen, dass sich write und read auf eine Datei beziehen. Das kann mit dem Prädikat open(F,M,N) erfolgen, wobei F der Dateipfad, M der Modus read oder write und N der Streamname sind: N wird benutzt, um write und read an die gewünschte Datei (oder das Gerät) zu koppeln. N muss ein Atom sein. Bei write und read ist der Streamname als erster Parameter anzugeben, also write(N,T) bzw. read(N,T), wobei T der zu schreibende oder lesende Text ist. Ist die Dateioperation beendet, so ist sie mit close(N) mit dem Streamnamen N zu schließen. Durch die Nennung des Stremnamens ist es möglich, mehrere Dateien oder Geräte gleichzeitig zu nutzen.

Eine zweite Möglichkeit besteht darin, eine Datei zum Schreiben mit tell(F) bzw. append(F) zu öffnen und dann mit told zu schließen bzw. zum Lesen mit see(F) zum Lesen zu öffenen und dann mit seen zu schließen, wobei F wiederum der Dateipfad ist. Man kann dann allerdings nicht mehrere Dateien oder Geräte gleichzeitig nutzen.
tell überschreibt eine Datei mit neuen Daten, append fügt einer Datei neue Daten hinzu. Ist die Datei noch nicht vorhanden, so legen tell und append diese neu an.

Beim Einlesen unserer Datenbankdaten sollen neue Klauseln erzeugt werden. Dies erfordert, dass die Daten in einer Form gespeichert werden, die beim Einlesen als Klauseln erkannt werden. write entfernt die Zeichen ' und " , writeq behält sie. Letzteres benötigen wir, damit nicht Wörter mit großen Anfangsbuchstaben als Variable interpretiert werden.
Zudem ist dafür zu sorgen, dass jede in einer Datei gespeicherte Klausel mit einem Punkt endet.

Beim Einlesen ist nicht bekannt, wann keine Daten mehr gelesen werden können. Dies muss getestet werden, damit das Programm nicht mit einer Fehlermeldung abbricht. Als Wahrheitswert liefert das Prädikat at_end_of_stream den Wert true, wenn keine Daten mehr gelesen werden können.

Mit diesen Werkzeugen lässt sich nun das Programm ergänzen:

Das Programm

ein(N,E):-asserta(dat(N,E)),append('c:/dat.pl'),
    writeq(dat(N,E)),write('.'),nl,told.
aus(N,E):-clause(dat(N,E),true).

inf:-see('c:/dat.pl'),in.
inf:-seen.
in:-not(at_end_of_stream),read(T),assert(T),in.

neue Daten aufnehmen, Datei zum Schreiben öffnen
Daten in Datei schreiben, Datei schließen
Daten suchen und ausgeben

Datei zum Lesen öffnen, Aufruf von Prädikat in
falls von in alle Daten gelesen, Datei schließen
wenn Dateiende nicht erreicht, Daten T lesen und in das Programm einfügen


Das Programm wird normal eingelesen und kompiliert, dann inf aufgerufen, um neue Daten aus der Datei dat.pl einzulesen. Danach folgende Aktionen:
Neue Daten aufnehmen mit Aufruf von ein(N,E), vgl. oben,
Daten suchen und ausgeben durch Aufruf von aus(N,E), vgl. oben
Das vollständige Programm kann unter datfil.pl geladen werden. Eventuell ist der Dateipfad vorher anzupassen.

Aufgabe: Man versuche, das Expertensystem zu ergänzen, dass Daten gespeichert und gelesen werden können.