Windows-Anbindung

Prolog und Windows vertragen sich vom Konzept her nicht. Prolog-Klauseln sollten theoretisch gleichzeitig auf den Wahrheitswert getestet werden, während Windows-Aktionen zeitlich gebunden stattfinden: Tastatur und Bildschirm müssen in bestimmten Zeitabständen angesprochen werden, damit die Anzeige stabil bleibt und die Tastatur nicht nur dann Eingaben ermöglicht, wenn ein Programm dies für einen kurzen Moment gestattet. Eingaben werden gepuffert, bis das Programm sie auswertet. Anzeigeaktionen werden ebenfalls gepuffert, da sie sich sonst optisch überschneiden können und ein Flackern auf dem Monitor entsteht. Die Kommunikation von Programmen mit den "Treiber-"Programmen für Tastatur und Bildschirm geschieht über Botschaften, die aufgrund der Pufferung zeitlich versetzt ausgewertet werden.

Entsprechend sendet und empfängt Prolog Botschaften, die in Prädikatform im Rumpf von Klauseln eingefügt werden. Es gibt da ein Problem:
Die Windows-Anzeige organisiert sich über Fenster, die eine bestimmte Kennung zur Unterscheidung erhalten. Diese Kennung kann in Prolog nur innerhalb einer Klausel genutzt werden oder in Prädikaten, die von dieser Klausel aus aufgerufen werden!

Wie das praktisch umgesetzt werden kann, werden wir anhand eines Datenbankprogramms sehen (vgl. letztes Kapitel).

Die Werkzeuge

Um Windows nutzen zu können, muss am Programmanfang mit :-use_module(library(pce)). die passende Prädikatenbibliothek eingebunden werden. SWI-Prolog kennt danach die folgenden Prädikate:

new(K,F)
Anlegen eines neuen Fensters: K Kennung, vom System erzeugt,F Fensterart, z.B. dialog, frame, picture

  dialog , frame:   Fenster für Ein-, Ausgabeelemente (s. unten)
picture:   Fenster für Grafiken
Nach dialog bzw. picture kann in Klammern einen Text eingeben, der im Fensterkopf angezeigt wird, also z.B. new(A,dialog('Fenster')).

Hat man dialog gewählt, so kann man für dieses Fenster Ein-Ausgabeelemente festlegen, indem man new erneut aufruft und dann statt F u.a. angibt:
button(S):   Steuerknopf mit der Spezifikation S, siehe unten
text_item(T):   Zeile zur Ein-/Ausgabe von Text T
int_item(Z)):   Zeile zur Ein-/Ausgabe von Zahl Z

Hat man picture gewählt, so kann man nach einem erneuten new Grafikelemente bestimmen:
bit_map(I)):   Bitmap mit dem Dateiname I und evtl. weiteren Angaben)
box(L,B)):   Rechteck mit der Länge L und der Breite B
circle(R)):   Kreis mit dem Radius R
line(AX,AY,EX,EY)):   Strecke von (AX,AY) nach (EX,EY)

Bei beiden Fensterarten dialog und picture kann man mit einem erneuten new Texte ausgeben lassen:
text(T)):   Text T, eingeschlossen in ', wird angezeigt


send(K,display,O)     ,     send(K,display,O,point(X,Y))
Vorbereitungen zumr Anzeige eines Objekts O im Fenster mit der Kennung K, Anfangsposition des Objekts (X,Y)
send(K,append,O)
Vorbereitungen zum Anzeige eines Objekts O im Fenster K, Anordnung vom System bestimmt

send(K,open)
Anzeigen aller Objekte im Fenster K
send(K?frame,free)
Schließen des Fensters K

Mit get(...) kann man Daten auslesen, dies soll hier nicht näher beschrieben werden. Unser Ziel ist es, dass durch das Betätigung eines Button ein Prädikat aufgerufen wird, das dann die Daten verarbeitet, die vorher in Fenstern eingegeben wurden.
Dazu dient der Befehl message, der wartet, bis die Daten vorliegen, um sie dann an das Prolog-Prädikat zu senden. message ist bei der Definition eines Button einzurichten:

button(T,message(K?frame,free))
Bei Betätigen des Button wird das Fenster K geschlossen. T ist die Aufschrift des Button.
button(T,message(@prolog,P,DL))
Bei Betätigen des Button wird das Prädikat P aufgerufen und die Daten der Liste DL an P übermittelt. Die Listenelemente sind durch Komma zu trennen.

Wie erhält man die Daten? Jedes Eingabelement hat über new eine Kennung K zugeteilt bekommen. K?selection sind dann die Daten des Objekts K.
Beispiel:
send(W,append,new(T,text_item('Frage?')),
send(W,append,new(K,button('Daten verarbeiten',message(@prolog,test,T?selection)))

Der erste send-Befehl legt im Fenster W eine Eingabezeile mit der Kennung T an. Der zweite send-Befehl legt in W einen Button an, der bei Betätigen das Prolog-Prädikat test aufruft, das einen Text als Parameter erwartet. Dieser Text ist dabei der Text, der in der Zeile T eingegeben wurde. Wie das Beispiel zeigt, kann man bei text_item in Klammern als Parameter eine Frage vorgeben, die in der Eingabezeile zu beantworten ist. Ein etwaiger zweiter Parameter kann als Antwortvorgabe eingesetzt werden.

Will man nach der Erstellung von text_item die Antwortvorgabe ändern, so kann man dies mit:
send(K,selection,Text)
Dabei steht K für die Kennung des text-item-Objekts.

Damit stehen alle nötigen Werkzeuge zur Verfügung, um Aus- und Eingabe eines Datenbankprogramm über Windows zu organisieren:

Das Programm

:-use_module(library(pce)).

anf:- new(D,dialog('Eingabe')),
    send(D,append,new(N,text_item('Name'))),
    send(D,append,new(S,text_item('Strasse'))),
    send(D,append,new(O,text_item('Ort'))),
    send(D,append,button('Neu',message(@prolog,aufn,
            N?selection,S?selection,O?selection,N,S,O))),     send(D,append,button('Ausgabe',message(@prolog,ausg,
            N?selection,S,O))),
    send(D,append,button('Leer',message(@prolog,clr,N,S,O))),
    send(D,append,button('Ende',message(D?frame,free))),
    send(D,open).

clr(N,S,O):-send(N,selection,''),send(S,
    selection,''),send(O,selection,'').
aufn(ND,SD,OD,N,S,O):-assert(dat(ND,SD,OD)),clr(N,S,O).
ausg(V,S,O):-clause(dat(V,SD,OD),true),
    send(S,selection,SD),send(O,selection,OD).
 

Einbinden von Windows-Schnittstelle

Anlegen des Windows-Fensters:
Eingabezeilen für Name, Strasse, Ort mid den Kennungen N,S,O
 
 
Button 'Neu', wenn gedrückt, dann Aufruf des Prädikats aufn mit
  den Eingabedaten und den Kennungen N,S,O als Parameter
Button 'Ausgabe', wenn gedrückt, dann Aufruf des Prädikats ausg mit
  dem Namentext und den Kennungen N,S,O als Parameter
Button 'Leer' mit Aufruf des Prädikats clr zum Löschen der Anzeige
Button 'Ende', Programmende
Fenster wird aufgebaut und angezeigt

Überschreiben der Eingabezeilen durch leeren String

neuen Datensatz mit den neuen Daten anlegen, Anzeige löschen
Datensatz zum vorgegebenen Namen suchen, Daten in die entsprechnenden
  Eingabezeilen kopieren

Das Programm wird mit dem Prädikat anf gestartet. Man kann dann Adress-Daten in die Eingabezeilen eintippen und dann den Button 'Neu' betätigen, um die Daten zu speichern. Gibt man einen Namen ein, so werden nach Betätigen des Button Ausgabe die zugehörigen Daten angezeigt. Um die Eingabezeilen zu löschen, betätige man den Button 'Leer'. Mit dem Button 'Ende' wird das Programm beendet.

Das Programm ist erhältlich unter datgr.pl.


Aufgabe: Man entwickle eine Windows-Oberfläche zum Expertensystem!