Entwurf eines Kapitels für das Buch "Logo im Mathematikunterricht", das dann doch zu komplex und themenfremd war.
Ein Informationssystem
Hans und Anna treffen sich auf der Straße:
"Ich habe gehört, Otto liebt Erna."
"So."
"Liebt Erna Otto?"
"Ich weiß nicht."
"Wen liebt Erna?"
"Erna liebt Kurt. Erna liebt Waldi."
"Und Waldi liebt Erna."
"So?"
"Was macht Kurt?"
"Kurt malt Lisa."
"Erna liebt Kurt."
"Ich weiß"
So etwa könnte sich ein Gespräch zwischen ihnen entwickeln. Sie tratschen über ihre Bekannten und tauschen dabei in ganz unkomplizierter Weise ihre Informationen aus.
Informationsverarbeitung ist ein wichtiger Aufgabenbereich für Computer. Kann man mit einem Computer genauso einfach "reden"? Kann man das "Verhalten" eines Computers so gestalten wie das eines Menschen? Wir werden es versuchen und Programme entwickeln, die einen Dialog zwischen Benutzer und Computer ermöglichen, der einem Tratsch recht nahe kommt.
>>>>> Computer und Mensch - Was ich weiß, macht mich heiß!
Von einem Gespächspartner erwartet man, daß er zuhört, d.h. daß er Informationen aufnimmt und sie in sein "Wissen" einordnet. Man erwartet auch, daß er auf eine Frage hin nach bestem Wissen antwortet, und schließlich, wenn das Gespräch nicht einseitig verlaufen soll, daß er selbst einige Aussagen macht oder Fragen stellt. In einem Gespräch werden
- Information erfragt
- Information aufgenommen
- Information eingeordnet
- Information aus dem Gedächstnis abgerufen
- Information ausgegeben
Das ist sehr nüchtern betrachtet – computerlike! Zwischen Menschen kann auch leeres Geschwätzt unterhaltsam sein. Unausgesprochenes wird verstanden, Signale werden gedeutet, Stimmungen empfunden. Menschen lächeln mitunter und sind manchmal ungenießbar. Sie sehen die Dinge mal so und mal so und handeln nach keinem festen Schema. Menschen sind nicht berechenbar – wohl erzogen, aber nicht programmiert.
Aufgabe
Auch während der Schalterstunden einer Bank stellen sich viele Menschen vor dem Geldautomaten an, um Geld von ihrem Konto abzuheben. Warum? Schreibe auf, welcher Dialog zwischen Geldautomat und Bankkunden abläuft. Schreibe zum Vergleich auf, wie ein Gespräch zwischen einem freundlichen Bankangestellten und einem mürrischen Kunden verlaufen könnte. Nenne auch nebensächliche Beobachtungen. (Hat der Kassierer saubere Fingernägel?)
Aufgabe
Beschreibe den Aufenthalt in einem computerisierten Restaurant. Zum Vergleich schildere den Besuch eines Gasthofs.
Psst! Stimmt das?
Der erste Schritt bei der Entwicklung eines informationsverarbeitenden Systems besteht darin, die Struktur einer Information und die des gesamten Wissens festzulegen. Wir legen das einfachste Satzmuster zugrunde:
Subjekt – Prädikat – Objekt
Die Eingabe von Informationen erfolgt in der Form:
psst! [erna liebt kurt]
Eine Frage wird in der Form
stimmt? [erna liebt kurt]
gestellt.
Die eingegebenen Aussagen werden wir nicht einfach hintereinander (in einer Liste) abgespeichern. Dann müßte der Computer zur Beantwortung einer Frage unter Umständen sein gesamtes Wissen durchsuchen. Wir werden statt dessen alle Prädikate in einer Liste sammeln und zu jedem Prädikat eine besondere Liste anlegen, in der alle Sätze, die dieses Prädikat enthalten, aufgeführt sind.
Als erstes schreiben wir das Programm für die Eingabe. Wenn das Prädikat des neuen Satzes schon vorher einmal genannt worden ist, braucht nur die neue Aussage in der Liste, die dem Prädikat zugeordnet ist, eingetragen zu werden. Andernfalls muß zuvor die Liste der Prädikate um das neue Wort erweitert und dem neuen Prädikat eine (noch leere) Liste zugeordnet werden:
to psst! :satz
make "prädikat first butfirst :satz
if not memberp :prädikat :prädikate [ ~
make "prädikate lput :prädikat :prädikate ~
make :prädikat [] ~
]
ifelse memberp :satz thing :prädikat [ ~
print [ich weiß!] ~
] [ ~
print "so ~
make :prädikat lput :satz thing :prädikat ~
]
end
Das Programm PSST!
setzt voraus, daß bereits eine Liste mit dem Namen "PRAED
existiert. Sie muss also beim Start der Sitzung eingerichtet werden. Wir schreiben dafür ein kleines Programm:
to init
erase names
make "prädikate []
end
Zur Veranschaulichung vergleichen wir verschiedene Eingaben und verfolgen den Programmablauf.
Wir gehen einmal davon aus, daß Sätze mit den Prädikaten LIEBT
und MALT
bereits eingeben wurden und folgende Variablen existieren:
pons
Make "prädikate [liebt malt]
Make "liebt [[erna liebt waldi] [waldi liebt erna]]
Make "malt [[kurt malt lisa]]
-
Wenn die neue Aussage:
psst! [otto ruft erna]
eingegeben wird<,br> werden im Programmpsst!
folgende Befehle ausgeführt:make "prädikat "ruft make "prädikate [liebt malt ruft] make "ruft [] print "so ~ make "ruft [[otoo ruft erna]]
Beachte: Nach
make "prädikat "ruft
istthing :prädikat
gleichbedeutend mitthing "ruft
, und das ist:ruft
. -
Es gibt eine weitere Aussage:
psst! [erna liebt kurt]
Im Programmpsst!
werden folgende Befehle ausgeführt:make "prädikat "liebt print "so? Make "liebt [[erna liebt waldi] [waldi liebt erna] [erna liebt kurt]]
-
Es wird Bekanntes eingegeben:
psst! [kurt malt lisa]
Im Programm wird ausgeführt:make "prädikat "malt print [ich weiß!]
Nachdem der Computer mit Information gefüttert wurde, sollen diese auch abgerufen werden. Die Beantwortung einer Frage ist – bei den geringen Ansprüchen, die bisher gestellt werden – einfach:
to stimmt? :satz
make "prädikat first butfirst :satz
make "pädikatsätze thing :prädikat
test memberp :satz :prädikatsätze
iftrue [print "ja]
iffalse [print [ich weiß nicht]]
end
Aufgabe
Gib die Programme ein und probiere:
init
psst! [otto ruft erna]
psst! [erna liebt kurt]
psst! [erna liebt waldi]
psst! [waldi liebt erna]
psst! [kurt malt lisa]
stimmt? [kurt malt lisa]
stimmt? [erna liebt otto]
Mit dem Befehl po names
werden die gespeicherten Daten aufgelistet, und die Struktur wird sichtbar.
Make "prädikate [ruft liebt malt]
Make "ruft [[otto ruft erna]]
Make "liebt [[erna liebt kurt] [erna liebt waldi] [waldi liebt erna]]
Make "malt [[kurt malt lisa]]
Mit diesen Daten werden wir unsere Programme testen.
Aufgabe
Bei Eingabe von
stimmt? [erna mag otto]
bricht die Programmausführung mit einer Fehlermeldung ab. Kläre, woran das liegt.
Irgendjemand da?
Wir wollen wissen, ob Erna irgendjemanden liebt. Der Computer soll uns auf
stimmt? [erna liebt #]
mit ja
oder ich weiß nicht
antworten.
Das Objekt ist uns nicht bekannt, und wir wollen es auch nicht erfahren. Wir geben # als "Joker" an. Auch für das Subjekt bzw. für beide, Subjekt und Objekt, soll ein Joker eingesetzt werden können:
stimmt? [# liebt #]
Weil die gespeicherten Sätze kein #
enthalten, wird test memberp :satz :prädikatsätze
immer "false
sein. Wir benötigen statt memberp
eine andere Prozedur, nennen wir sie passt_einer?
.
Das Programm passt_einer?
soll klären, ob unter den gespeicherten Sätzen mindestens einer – bis auf die Jokerplätze – dem genannten Muster übereinstimmt.
to passt_einer? :muster :sätze
if emptyp :sätze [output "false]
if passt? :muster first :sätze [output "true]
output passt_einer? :muster butfirst :sätze
end
Den Vergleich des Musters mit einem bestimmten Satz muss wieder ein weiteres Programm erledigen:
to passt? :muster :satz
if and :muster=[] :satz=[] [output "true]
if or :muster=[] :satz=[] [output "false]
if or (first :muster) = "# (first :muster) = (first :satz) [~
output passt? butfirst :muster butfirst :satz~
]
output "false
end
Aufgabe
Gib die Programmtexte ein (zuerst das tiefer geschachtelte passt?
) und kontrolliere ihre Funktion durch:
passt? [erna liebt #] [erna liebt kurt]
passt? [# liebt kurt] [erna liebt kurt]
passt? [# liebt lisa] [erna liebt kurt]
Kontrolliere dann die Ausgaben der folgenden Anfragen:
passt_einer? [erna liebt #] :liebt
passt_einer? [# liebt kurt] :liebt
passt_einer? [# liebt #] :liebt
passt_einer? [# mag #] :liebt
Hinweis: :liebt
gleich [[erna liebt kurt][erna liebt waldi][waldi liebt erna]]
Jetzt wenden wir uns wieder dem Programm stimmt?
zu und nehmen die angekündigte Änderung vor.
to stimmt? :satz
make "prädikat first butfirst :satz
make "pädikatsätze thing :prädikat
test passt_einer? :satz :prädikatsätze
iftrue [print "ja]
iffalse [print [ich weiß nicht]]
end
Aufgabe
Gib den Programmtext ein und kontrolliere ihre Funktion durch:
stimmt? [erna liebt #]
Hoppla, da stimmt etwas nicht!
stimmt? [# liebt kurt]
stimmt? [# liebt #]
stimmt? [erna # kurt]
Wenn ein Joker in der Mitte an der Stelle des Prädikats steht, existiert thing "#
nicht. Weil das Prädikat nicht bekannt ist, kann natürlich auch nicht gezielt in der Satzliste des Prädikats gesucht werden. In diesem Fall müssen alle Sätze begutachtet werden.
to stimmt? :satz
make "prädikat first butfirst :satz
test :prädikat = "#
iftrue [make "prädikatsätze alle_sätze :prädikate]
iffalse [make "prädikatsätze thing :prädikat]
test passt_einer? :satz :prädikatsätze
iftrue [print "ja]
iffalse [print [ich weiß nicht]]
end
Wieder muss ein zusätzliches Programm Hilfe leisten. Das ist typisch für die rekursive funktionale Programmiersprache Logo.
to alle_sätze :prädikate
print :prädikate
if :prädikate = [] [output []]
output sentence thing first :prädikate alle_sätze butfirst :prädikate
end
Aufgabe
Gib die Programmtexte ein und kontrolliere ihre Funktion durch:
allesätze [liebt]
Und dann
:prädikate
alle_sätze :prädikate
stimmt? [# liebt kurt]
stimmt? [# liebt #]
stimmt? [erna # kurt]
Kleine Ergänzungen
Die Raute #
als Joker ist nicht schön. Klangvoller sind Sätze wie
oder
stimmt? [jemand liebt kurt]
stimmt? [jemand liebt jemanden]
stimmt? [erna etwas kurt]stimmt? [erna ? kurt]
Um das zu erreichen, muss in stimmt?
nur der besser klingenden Satz in das bisher verwendet Format überführt werden. Dann kann der Rest des Programms unverändert bleiben.
to joker :satz
if :satz = [] [output []]
if memberp first :satz [jemand etwas ? ~ jemanden] [ ~
output fput "# joker butfirst :satz ~
]
output fput first :satz joker butfirst :satz
end
to stimmt? :satz
make "satz joker :satz
...
Aufgabe
Gib das Programm joker
ein teste es.
Erweitere das Programm stimmt?
und teste die neue Funktionalität.
Eingabe und Abfrage von Information können komfortabler erfolgen. Wir vereinbaren: Jede Aussage endet mit einem Punkt. Jede Frage endet mit einem Fragezeichen. Als Promptzeichen soll am Anfang jeder Eingabezeile ein >
gedruckt werden, zum Beispiel
>otto liebt erna.
so.
>erna liebt otto?
ich weiss nicht.
>erna liebt kurt?
ja
># malt #?
ja
>
Aufgabe
Schreibe dafür ein Programm mit dem Namen TRATSCH
und teste es.
Anleitung:
type ">
schreibt den Promt ohne Zeilenvorschub.- Wenn hinter dem > noch ein Leerzeichen ▮ stehen soll, muss im Befehl durch einen vorangestellten Backslash \ maskiert werden:
type ">\▮
- Durch
make "eingabe readlist
wird die Eingabe des Benutzers erfasst und gespeichert. - Das letzte Zeichen des letzten Wortes des eingegebenen Satzes
:satz
wird durchmake "zeichen last last :eingabe
ermittelt. - Je nachdem, ob
:zeichen
ein Punkt oder ein Fragezeichen ist, wird das Programmpsst!
oder das Programmstimmt?
gestartet. - Als Parameter erwarten
psst!
undstimmt?
einen Satz ohne Punkt oder Fragezeichen am Ende. Diesen um das letzte Zeichen des letzten Wortes gekürzten Satz erhält man mitlput butlast last :eingabe butlast :eingabe
- Wenn das letzte Zeichen der Eingabe weder ein Punkt noch ein Fragezeichen ist, gibt
tratsch
die Antwortwie bitte?
. - Am Ende des Programms ruft sich
tratsch
zwecks Wiederholung selbst auf.
wer was wen?
Das System wird nun so erweitert, daß auch Fragen wie wer liebt kurt?
konkret beantwortet werden können. In diesem Fall wird nicht mit wahr
oder falsch
geantwortet (wie das oben bereits gelöst wurde). Das Wort wer
steht hier als Platzhalter für Einsetzungen, die die Aussage erfüllen, und das Ergebnis wird eine Liste möglicher Einsetzungen sein.
Auch Fragen nach dem Objekt und dem Prädikat werden erlaubt:
erna liebt wen?
wer liebt wen?
erna was kurt?
Die grammatikalische Umstellung wen liebt erna?
werden wir zunächst nicht zulassen, weil die Programmierung einfacher ist, wenn immer die Reihenfolge Subjekt-Prädikat-Objekt einhalten wird. (Verändern wir wegen der Computer unsere Sprache?)
Wir stellen die Anfragen vorerst in der Form
suche [wer liebt kurt]
suche [erna liebt wen]
suche [wer liebt wen]
suche [wer liebt lisa]
mit den Platzhaltern wer
, was
, wen
.
[[erna % %]]
[[% % kurt] [% % waldi]]
[[otto % erna] [erna % kurt] [erna % waldi]]
[]
[erna]
[kurt waldi]
[otto~erna erna~kurt erna~waldi]
[]
Zur Erinnerung: Das Wissen unseres Informationsystem besteht aus einer Sammlung von zuvor eingegebenen Sätzen.
Make "PRÄDIKATE [ruft liebt malt]
Wenn das Prädikat bekannt ist, kann die Suche auf Liste beschränkt werden, die zu diesem Prädikat angelegt wurde. Wenn nicht, müssen die Listen aller Prädikate duchsucht werden.
Make "RUFT [[otto ruft erna]]
Make "LIEBT [[erna liebt kurt] [erna liebt waldi] [waldi liebt erna]]
Make "MALT [[kurt malt lisa]]
Das Programm suche
beauftragt ein anderes Programm festzustellen, welche Sätze die angegebene Aussageform erfüllen können. Es werden etliche Unterprogramme benötigt, um das Programm suche
schliesslich starten können.
to suche :muster
if not (count :muster) = 3 [output []]
make "prädikat first butfirst :muster
if :prädikat = "was [output durchsuche :muster :prädikate]
if memberp :prädikat :prädikate [output durchsuche :muster (list :prädikat)]
output []
end
(list :prädikat)
ist erforderlich, weil durchsuche
als zweiten Parameter eine Liste erwartet.
to durchsuche :muster :prädikatliste
if :prädikatliste = [] [output []]
output sentence ~
(durchsuche_sätze :muster thing first :prädikatliste) ~
(durchsuche :muster butfirst :prädikatliste)
end
to durchsuche_sätze :muster :sätze
if :sätze = [] [output []]
if not (count first :sätze) = 3 [output []]
output sentence ~
(vergleiche :muster first :sätze [wer was wen] []) ~
(durchsuche_sätze :muster butfirst :sätze)
end
Und immer weiter wird delegiert. Gut wir so viel Personal haben...
to vergleiche :muster :satz :platzhalter :ergebnis
if :satz = [] [output (list :ergebnis)]
make "gefunden "
if (first :muster) = (first :platzhalter) [make "gefunden first :satz]
if (first :muster) = (first :satz) [make "gefunden "%]
if :gefunden = " [output []]
output vergleiche bf :muster bf :satz bf :platzhalter lput :gefunden :ergebnis
end
Jetzt werden die Programme gestestet, die letztgenannten zuerst, denn sie werden bei den vorstehenden benötigt.
vergleiche [wer liebt kurt] [erna liebt kurt] [wer was wen] []
vergleiche [erna liebt wen] [erna liebt kurt] [wer was wen] []
vergleiche [wer liebt wen] [erna liebt kurt] [wer was wen] []
vergleiche [wer liebt lisa] [erna liebt kurt] [wer was wen] []
[[erna % %]]
[[% % kurt]]
[[erna % kurt]]
[]
Zum Prädikat liebt
liegen die meisten Sätze vor: :liebt = [[ERNA LIEBT KURT][ERNA LIEBT WALDI][WALDI LIEBT ERNA]]
. Also wird getestet:
durchsuche_sätze [wer liebt wen] :liebt
durchsuche_sätze [wer liebt lisa] :liebt
durchsuche_sätze [wer was erna] :liebt
durchsuche_sätze [wer was erna] alle_sätze :prädikate
durchsuche_sätze [wer was wen] alle_sätze :prädikate
[[erna % kurt] [erna % waldi] [waldi % erna]]
[]
[[waldi liebt %]]
[[otto ruft %] [waldi liebt %]]
[[otto ruft erna] [erna liebt kurt] [erna liebt waldi] [waldi liebt erna] [kurt malt lisa]]
Beachte, dass das Ergebnis on durchsuche_sätze [wer was erna]
davon abhängt, was als Parameter :sätze
mitgegeben wird. In suche
wird das über den Test if :prädikat = "was ...
kontrolliert.
durchsuche
erwartet als zweiten Parameter eine Liste von Prädikaten, deren Satzlisten durchsucht werden sollen.
durchsuche [wer liebt wen] [liebt]
durchsuche [wer liebt lisa] [liebt]
durchsuche [wer was erna] [liebt ruft]
durchsuche [wer was erna] :prädikate
durchsuche [wer was wen] :prädikate
[[erna % kurt] [erna % waldi] [waldi % erna]]
[]
[[waldi liebt %] [otto ruft %]]
[[otto ruft %] [waldi liebt %]]
[[otto ruft erna] [erna liebt kurt] [erna liebt waldi] [waldi liebt erna] [kurt malt lisa]]
Kommen wir zum Programm suche
, in dem die zu betrachtenden Prädikate automatisch bestimmt werden.
suche [wer liebt wen]
suche [wer liebt lisa]
suche [wer was erna]
suche [wer was wen]
suche [wer mag erna]
[[erna % kurt] [erna % waldi] [waldi % erna]]
[]
[[otto ruft %] [waldi liebt %]]
[[otto ruft erna] [erna liebt kurt] [erna liebt waldi] [waldi liebt erna] [kurt malt lisa]]
[]
Die Ergebnisse sind wie erwartet!
Aufgabe
Das Programm tratsch
soll so geändert werden, daß es bei einem Fragesatz selbst entscheidet, ob es stimmt?
oder suche
aufruft. Erweitere tratsch
entsprechend.
Anleitung:
suche
soll genau dann aufgerufen werden, wenn das Muster eines der Worte wer, was, wen enthält, also wenn schnittmenge :muster [wer was wen]
nicht leer ist.
to schnittmenge :a :b
if emptyp :a [output []]
test memberp first :a :b
iftrue [output fput first :a intersection butfirst :a :b]
iffalse [output intersection butfirst :a :b]
end
Aufgabe
Als Ergebnis einer Suche sollen ganze Sätze ausgeben werden. Dazu wird dem Programm suche
wird ein anderes Programm vorgeschaltet, das die Ausgabe aufbereitet.
sag [wer liebt wen]
erna liebt kurt .
erna liebt waldi .
waldi liebt erna .
sag [wer liebt lisa]
das weiß ich nicht.
Anleitung:
to sag :muster
make "antwort suche :muster
test :antwort = []
iftrue [print [das weiß ich nicht .]]
iffalse [schreibe :muster]
end
to schreibe :muster :antwort
if :antwort = [] [stop]
(print (ersetze :muster first :antwort) ".)
schreibe :muster butfirst :antwort
end
to ersetze :muster :antwort
if :muster = [] [output []]
test (first :antwort) = "%
iftrue [output fput first :muster ersetze butfirst :muster butfirst :antwort]
iffalse [output fput first :antwort ersetze butfirst :muster butfirst :antwort]
end
Teste die Programme.
ersetze [wer liebt wen] [erna % kurt]
ersetze [wer liebt kurt] [erna % %]
ersetze [erna liebt wen] [% % kurt]
ersetze [wer was wen] [erna liebt kurt]
schreibe [erna liebt wen] [[% % kurt] [% % waldi]]
sag [wer liebt wen]
sag [wer liebt kurt]
sag [erna liebt wen]
sag [wer was wen]
Mit stimmt?
und suche
können nun Informationen aus dem System abgerufen werden. stimmt?
antwort nur mit ja oder ich weiß nicht. suche
listet alle möglichen Einsetzungen auf.
stimmt? [# liebt #]
In der wohlklingen Version
ja
stimmt? [jemand liebt jemanden]
ja
suche [wer liebt wen]
[[erna % kurt] [erna % waldi] [waldi % erna]]
Die Abfrage suche [wer liebt jemanden]
liefert aber das falsche Ergebnis []
.
Die gewünschte Antwort wäre
[[erna % %] [waldi % %]]
Aufgabe
Das Programm tratsch
soll selbständig Aussagen machen. Damit das nicht zu oft passiert, entscheidet ein "Würfel" darüber.
Anleitung:
- Mit
random 6
wird scheinbar zufällig eine aus dem Bereich [0,1,2,3,4,5] gewählt.
Will man wie bei einem Würfel einer der Zahlen [1,2,3,4,5,6] erhalten, muss man 1 addieren:(1 + random 6
). - Das Programm
tratsch
soll nur dann "selbst reden", wenn eine 6 gewürfelt wird:
if (1 + random 6) = 6 [quassel]
Genauso gut wäre
if random 6 = 5 [quassel]
Im Programm
quassel
werden von allen gespeicherten Sätzen drei zufällig ausgewählt. Aus diesen Sätzen wird werden dann Subjekt, Prädikat und Objekt entnommen.to quassel make "sätze alle_sätze :Prädikate make "n count :sätze make "subjekt first item (1 + random :n) :sätze make "prädikat first butfirst item (1 + random :n) :sätze make "objekt last item (1 + random :n) :sätze (print :subjekt :prädikat :objekt) end
Diese Methode ist sehr ineffektiv. Hier soll nur Möglichkeit einer generierter Texte demonstriert werden.
Ich denke ...
Lisa
erwartet Erna. Wir schließen daraus, daß Erna Lisa
besuchen wird. Auch wenn es dem Computer nicht ausdrücklich
eingegeben wurde, sollte er im Anschluß an die Eingabe
PSST!
[LISA ERWARTET ERNA]
auf
die Frage
STIMMT?
[ERNA BESUCHT LISA]
mit JA antworten. Damit der Computer diese Schlußfolgerung ziehen kann, muß ihm die Regel "Wenn x y erwartet, dann besucht y x" bekannt sein. Wir wollen sie in der Form
FOLGERE.AUS [X BESUCHT Y] [Y ERWARTET X]
eingeben. Wir verwenden hier die ungewohnte Reihenfolge "Folgerung ‹= Voraussetzung", weil in der Folgerung unbedingt die Platzhalter X (für das Subjekt) und Y (für das Objekt) verwendet werden sollen. Die nun anstehende Programmierung wird durch diese übereinkunft etwas vereinfacht.
Ja, wie programmieren wir diese Fähigkeit des Computers, mittels Schlußregeln aus begrenztem Wissen weiteres Wissen zu gewinnen?
Wenn die Aussage "x besucht y" aus "y erwartet x" abgeleitet werden kann, müssen zur Beantwortung der Frage "x besucht y" nicht nur alle Aussagen, die das Prädikat "besucht" enthalten, sondern auch die mit dem Prädikat "erwartet" durchsucht werden.
Der Computer muß also zu jedem Prädikat festhalten, welche weiteren Prädikate zu untersuchen sind. Wir führen dafür weitere Listen ein, die wir wieder mit dem Prädikatnamen bezeichnen. Den Namen dieser "Regel"-Listen wird zur Unterscheidung von den bisher eingeführten "Aussage"-Listen ein $-Zeichen vorangestellt (als "BESUCHT und "$BESUCHT).
INIT
PSST!
[OTTO LIEBT ERNA]
PSST! [ERNA LIEBT KURT]
PSST!
[ERNA LIEBT WALDI]
PSST! [WALDI LIEBT ERNA]
PSST!
[KURT MALT LISA]
PSST!
[OTTO MALT OTTO]
PSST!
[LISA ERWARTET ERNA]
FOLGERE.AUS [X
BESUCHT
Y]
[Y
ERWARTET
X]
FOLGERE.AUS
[X BESCHENKT Y][X BESUCHT Y]
FOLGERE.AUS [X BESCHENKT
Y][X LIEBT Y]
wird die folgende Struktur aufgebaut sein:
"LIEBT
IST [[OTTO LIEBT ERNA][ERNA LIEBT KURT][ERNA LIEBT WALDI][WALDI LIEBT
ERNA]]
"MALT IST [[KURT MALT LISA][OTTO MALT OTTO]]
"ERWARTET
IST [[LISA ERWARTET ERNA]]
"BESUCHT IST []
"BESCHENKT
IST []
"$LIEBT IST []
"$MALT IST []
"$ERWARTET
IST []
"$BESUCHT IST [[Y ERWARTET X]]
"$BESCHENKT IST
[[X BESUCHT
Y][X
LIEBT
Y]]
Was ist nun zu tun, wenn gefragt wird: Wen beschenkt Erna? Es müssen alle Eintragungen unter dem Namen BESCHENKT geprüft werden, ferner die unter LIEBT und die unter BESUCHT. Dabei wird sich herausstellen, daß auch unter ERWARTET Antworten zu finden sind.
überlegen
wir genauer, wie die Frage
SUCHE
[ERNA BESCHENKT X]
vom Computer beantwortet werden kann. Die Liste BESCHENKT ist leer. Es liegt keine Aussage der Form "... beschenkt ..." vor. Aber in $BESCHENKT ist abzulesen, daß [X BESCHENKT Y] aus [X BESUCHT Y] und aus [X LIEBT Y] abzuleiten ist. Die Liste BESUCHT ist leer. Aber aus $BESUCHT geht hervor, daß [X BESUCHT Y] aus [Y ERWARTET X] folgt. Beachte die geänderte Reihenfolge von X und Y. Ausgehend von [ERNA BESCHENKT X] prüft der Computer nun [X ERWARTET ERNA]. Diese Aussageform wird mit LISA als X erfüllt; denn ERWARTET enthält die Aussage [LISA ERWARTET ERNA]. Die Liste $ERWARTET ist leer. In dieser Richtung braucht also nicht weitergesucht zu werden. Soweit gut! Nun ist noch [ERNA LIEBT X] zu prüfen. In LIEBT liegen die passenden Aussagen [ERNA LIEBT KURT] und [ERNA LIEBT WALDI] vor. Auch KURT und WALDI sind also mögliche Einsetzungen für X. Weitere Lösungen sind in LIEBT nicht zu finden, und auch $LIEBT ist leer. Die Suche ist beendet, das Ergebnis (die Liste aller Lösungen) lautet:
[[LISA % %][KURT % %][WALDI % %]].
Wir erweitern nun unser Informationssystem und schreiben zunächst das Programm FOLGT.AUS:
PR
FOLGT.AUS :FOLGERUNG :VORAUS
SETZE "P ER OE
:FOLGERUNG
WENN NICHT EL? :P :PRAED DANN ...
... SETZE
"PRAED ML :P :PRAED SETZE :P [] SETZE (WORT "$ :P)
[]
PRUEFE EL? :VORAUS (WERT WORT "$ :P)
WW
DZ [ICH WEISS]
WF DZ [GUT] SETZE (WORT "$ :) ML
:VORAUS (WERT WORT "$ :P)
ENDE
Das Programm bestimmt zunächst das Prädikat P in FOLGERUNG. Wenn es bisher noch nie genannt wurde, wird es wie in PSST! in die Prädikatliste aufgenommen, und die Listen für die zugehörigen Aussagen und die zugehörigen Voraussetzungen werden initialisiert. Nachdem auf diese Weise sichergestellt ist, daß die Listen zu P existieren, wird die eingegebene Voraussetzung VORAUS in die Liste mit dem Namen WORT "$ :P aufgenommen.
Die
$-Liste zu einem Prädikat muß auch im Programm
PSST!
initialisiert
werden.
Erweitere die Zeile
WENN
NICHT EL? :P :PRAED DANN SETZE "PRAED ML :P :PRAED SETZE :P []
zu:
WENN
NICHT EL? :P :PRAED DANN SETZE "PRAED ML :P :PRAED SETZE :P []
...
... SETZE (WORT "$ :P) []
Wenn
eine Schlußfolgerung in der Form
AUS.FOLGERE
[X
BESUCHT
Y]
[Y
ERWARTET
X]
geschrieben
werden soll, benötigen wir nur ein Fassaden-Programm:
PR
AUS.FOLGERE :A :B
RG FOLGERE.AUS :B :A
ENDE
Nun
muß das SUCHE-Programm
angepaßt werden. Es reicht nicht mehr aus, durch
SAMMLE
:S (WERT ER OE :S)
die Liste der zu dem Prädikat gemachten Aussagen zu durchsuchen (z.B. die zu BESCHENKT gehörige Liste []). Denn zu den dort gefundenen Einsetzungen kommen noch jene hinzu, die beim Prüfen aller möglichen Voraussetzungen (in diesem Fall der in $BESCHENKT, also in [[X BESUCHT Y][X LIEBT Y]]) ermittelt werden. Wir lassen diese weiteren Lösungen von einem Programm EINES bestimmen und vereinigen beide Ergebnislisten. Wir erweitern das Programm deshalb SUCHE zu:
PR
SUCHE :S
SETZE "P ER OE :S
PRUEFE
EL? :P :PRAED
WW RG VEREINIGUNG (SAMMLE
:S WERT :P) (EINES
WERT WORT "$ :P)
WF RG []
ENDE
Das Programm EINES erhält als Eingabe eine Liste von Ausagen bzw. Aussageformen. Es gibt Einsetzungen für X, Y, Z zurück, die mindestens einen dieser Aussagen bzw. eine dieser Aussageformen erfüllen:
PR
EINES :L
WENN :L = [] DANN RG []
RG
VEREINIGUNG (SAMMLE ER :L) (EINES OE :L)
ENDE
Das Programm VEREINIGUNG findest du im Anhang. Gib es ein, und teste es sogleich.
Wenn
alle Programme verändert bzw. neu eingegeben sind, kann das
System getestet werden. Gib dann die oben genannten Aussagen und
Schlußregeln ein. Versichere dich zunächst durch
ZEIGE
NAMEN
davon,
daß die Eingaben wie gewünscht in Listen abgespeichert
werden. Probiere:
SUCHE
[X LIEBT Y]
Das Ergebnis ist:
[[OTTO ERNA %][ERNA KURT %][ERNA WALDI %]].
Richtig.
Nun aber:
SUCHE
[ERNA BESCHENKT X]
Die Antwort des Computers ist falsch:
[[LISA ERNA][ERNA KURT %][ERNA WALDI]]
Wo liegt der Fehler?
Beim
Aufruf SUCHE
[ERNA BESCHENKT X] ruft
SUCHE
seinerseits das
Programm SAMMLE
auf, dem es den
Wert von BESCHENKT
(hier gleich
[])
übergibt. Dann startet es das Programm EINES
mit dem Wert von
$BESCHENKT
(der ist hier [[Y
BESUCHT X][X LIEBT Y]])
auf. Das Programm findet für [Y
BESUCHT X] die
Einsetzung [LISA
ERNA %] – und
das liegt bereits der Fehler! Um das richtige Ergebnis zu erhalten,
müssen in der Eingabe des Programms EINES
für X
und Y
die aktuellen Werte
eingesetzt werden. Das sind nach unserer übereinkunft das
Subjekt (für X)
und das Objekt (für Y)
des aktuellen Satzes. Wir schreiben eine Funktion ERSETZUNG,
der wir die Liste der Voraussetzungen übergeben, das die
gewünschen Werte für X
und Y
einsetzt. Im
Programm SUCHE
heißt es
nun:
WW
RG VEREINIGUNG
(SAMMLE
:S WERT
:P)
...
... (EINES ERSETZUNG (ER :S) (LZ :S) WERT WORT "$
:P)
Nimm diese änderung vor. Das neue Programm ERSETZUNG lautet:
PR
ERSETZUNG :X :Y :L
WENN :L = [] DANN RG []
WENN
LISTE? ER :L DANN RG ME (ERSETZUNG :X :Y ER :L) (ERSETZUNG :X :Y OE
:L)
WENN ER :L = "X DANN RG ME :X (ERSETZUNG :X
:Y ER :L)
WENN ER :L = "Y DANN RG ME :Y
(ERSETZUNG :X :Y ER :L)
RG ME (ER :L) (ERSETZUNG :X :Y
ER :L)
ENDE
Gib
diesen Text ein, und teste die Wirkung des Programms
durch:
ERSETZUNG
"ERNA "X [X LIEBT Y]
ERSETZUNG "ERNA
"KURT [X LIEBT Y]
ERSETZUNG "A
"B
[[X
LIEBT
Y][X
BESUCHT
Y]]
Wie ist es möglich, daß dieses Programm Listen von Listen abarbeiten kann?
Jetzt
arbeitet unser Informationssystem fehlerfrei:
SUCHE
[ERNA BESCHENKT X]
SUCHE [X BESCHENKT Y]
SCHLIESSE
[X BETRACHTET Y][X MALT Y]
SCHLIESSE [X BETRACHTET Y]
[X BEOBACHTET Y]
SCHLIESSE [X SIEHT Y][X BETRACHTET
Y]
PSST! [OTTO BEOBACHTET KURT]
SUCHE
[X SIEHT Y]
Aufgabe
Beschreibe eine Gruppe von Personen durch Sätze der Form Subjekt-Prädikat-Objekt. Lege einige Schlußfolgerungen fest. Gib diese Informationen und Regeln mit Hilfe der Programme PSST! und SCHLIESSE in den Computer ein, und stelle viele (dumme) Fragen.
Aufgabe
Wir wissen: Jede Primzahl ist natürlich. Jede natürliche Zahl ist ganz. Jede ganze Zahl ist rational. Jede rationale Zahl ist reell. 19 ist Primzahl. 12 ist natürlich. -5 ist ganz. 3/2 ist rational. Die Zahl π (PI) ist reell.
Gib diese Regeln und Aussagen ein, und laß mitteilen, welche der genannten Zahlen ganz (rational, reell) sind.
Aufgabe
über Vierecke wissen wir: Jedes Quadrat ist ein Rechteck. Jedes Quadrat ist ein Rhombus. Jedes Rechteck ist ein Trapez. Jedes Rechteck ist ein Parallelogramm. Jeder Rhombus ist ein Parallogramm. Jeder Rhombus ist ein Drachen. Jedes Parallelogramm ist ein Trapez.
Gib
diese Gesetze in der Form
SCHLIESSE
[X RECHTECK][X QUADRAT]
ein.
Erfinde auch die Namen einiger Vierecke, z.B.:
PSST!
[FENSTER RECHTECK]
PSST! [P PALLELOGRAMM]
Frage
dann, welche Trapeze vorliegen und ob z.B. FENSTER
ein Drachen
ist:
SUCHE
[X TRAPEZ]
STIMMT? [FENSTER DRACHEN]
überlege,
welche Regeln einzugeben sind, wenn der Computer auch die
Fragen
SUCHE
[X ACHSENSYMMETRISCH]
SUCHE [X PUNKTSYMMETRISCH]
beantworten soll.
Aufgabe
Im
bereits beschriebene Programm TRATSCH
soll die Eingabe einer
Schlußfolgerung etwas eleganter in der Form
AUS
X BETRACHTET Y FOLGT X SIEHT Y .
erfolgen. Die Voraussetzung steht also zwischen den Worten AUS und FOLGT, die Folgerung zwischen FOLGT und dem Punkt. Benutze das im Anhang angegebene Programm TEIL, um die beiden Satzteile herausfischen zu lassen.
Wir
wollen LIEBT
und MAG
gleichwertig
verwenden (auch wenn das nicht ganz korrekt ist). Wir geben
ein:
SCHLIESSE
[X MAG Y][X LIEBT Y]
SCHLIESSE [X LIEBT Y][X MAG Y]
Anschließend
fragen wir:
SUCHE
[X MAG Y]
Der Computer sucht und sucht. Wir müssen die Programmausführung mit CTRL-G abbrechen.
Was ist passiert? Es gilt jetzt:
"$LIEBT
IST [[X MAG Y]]
"$MAG IST [[X LIEBT Y]]
"LIEBT IST
[[OTTO LIEBT ERNA][ERNA LIEBT KURT][ERNA LIEBT WALDI]]
"MAG
IST []
Nach
Eingabe von SUCHE
[X MAG Y] betrachtet
der Computer zunächst die Liste MAG,
die aber leer ist. Er verfolgt daraufhin die in $MAG
angegebenen
Aussageformen und untersucht die Liste LIEBT,
die drei Aussagen enthält. [OTTO
ERNA
%|,
[ERNA KURT
%] und [ERNA
WALDI %] werden als
Lösungen erkannt. Jetzt verfolgt der Computer $LIEBT,
sucht also nach Einsetzungen für die Aussageform [X
MAG Y]. Das hatten
wir aber schon! Ein Kreis hat sich geschlossen, und in diesem Kreis
dreht sich der Suchvorgang nun immerfort. Um diesen Fehler zu
beheben, müssen alle geprüften Aussageformen in einer Liste
gesammelt werden, so daß eine zweite Analyse verhindert werden
kann. Füge als erste Programmzeile in SUCHE
ein:
PRUEFE
EL? :S :GEPRUEFT
WW (DZ "GEPRUEFT :S) RG []
WF
(DZ "PRUEFE :S) SETZE "GEPRUEFT ML :S :GEPRUEFT
Natürlich
muß der Variable GEPRUEFT
anfangs vor
dem ersten Aufruf des Programms SUCHE
– die leere
Liste zugewiesen werden. Wo bringen wir die Anweisung
SETZE
"GEPRUEFT []
unter? Wir schreiben ein spezielles Programm mit dem Namen WELCHE, das diese Vorbereitung trifft und dann das Programm SUCHE aufruft:
PR
WELCHE :S
SETZE "GEPRUEFT []
RG
SUCHE :S
ENDE
Nimm
diese Erweiterungen vor, und gib dann ein:
SUCHE
[X ZEICHNET Y]
Die Antwort lautet nun: [[KURT LISA %]]
Im
Programm STIMMT?
berücksichtigen
wir diese änderung, indem wir dort nicht mehr SUCHE,
sondern WELCHE
aufrufen:
PRUEFE
(WELCHE :S) = []
Aufgabe
Zwischen
zwei Geraden in einer Ebene gilt mindestens eine der Beziehungen
GLEICH,
PARALLEL,
SCHIEF
(d.h. geschnitten),
SENKRECHT.
Beachte: Wenn a gleich b ist, dann ist auch b gleich a (und
entsprechend parallel, schief, senkrecht). Wenn zwei Geraden
senkrecht aufeinander stehen, dann schneiden sie sich auch. Wenn zwei
Geraden gleich sind, so verlaufen sie parallel. Gib diese
Schlußfolgerungen und einige Aussagen ein, z.B.:
PSST!
[G GLEICH H]
PSST! [H PARALLEL K]
Warum
ist das Ergebnis der Frage
WELCHE
[X PARALLEL K]
unbefriedigend?
14.4 xxx
Richtig
schön ist die Liebe bekanntlich, wenn sie beantwortet wird. Ob
uns der Computer wohl ein Liebespaar nennen kann? Er muß dazu
alle Einsetzungen für X
und Y
herausfinden, für
die gilt: X
liebt Y
und Y
liebt X.
Wir entwickeln ein Programm
ALLE,
das feststellt, welche Einsetzungen für X,
Y und
Z alle
in der Listen aufgeführten Aussageformen erfüllen. Dann
können wir fragen:
ALLE
[X LIEBT Y][Y LIEBT X]
>>> ERNA UND WALDI
Wenn keine Aussage/Aussageform in der Liste, díe dem Programm ALLE übergeben wird, steht, gibt es als Ergebnis die leere Menge zurück. Wenn nur eine Aussage(-form) vorliegt, ruft ALLE das Programm SUCHE auf, das die Tripel mit bekanntem Fleiß bestimmt und abliefert. Wenn zwei oder mehr Aussagen bzw. Aussageformen vorliegen, läßt das Programm zunächst einmal alle Tripel bestimmen, die die erste Aussage(-form) (ER :L) erfülen, und dann alle Tripel, die alle restlichen Aussagen/Aussageformen (OE :L) erfüllen. Die Schnittmenge beider Ergebnislisten liefert es ab:
PR
ALLE :L
WENN :L = [] DANN RG []
WENN OE
:L = [] DANN RG SUCHE ER :L
RG SCHNITT (SUCHE ER :L)
(ALLE OE :L)
ENDE
Das
Programm SCHNITT
findest du im
Anhang. Gib die Programmtexte ein und teste:
ALLE
[[X LIEBT Y][Y LIEBT X]]
In diesem Fall ergibt SUCHE [X LIEBT Y] das Ergebnis [[ERNA KURT %][ERNA WALDI %] [WALDI ERNA %]]. Der Aufruf ALLE OE :L führt zur Aufgabe SUCHE [Y LIEBT X]] und liefert das Ergebnis [[KURT ERNA %][WALDI ERNA %][ERNA WALDI %]]. Die Schnittmenge beider Antworten ist [[ERNA WALDI %][WALDI ERNA %]], und das ist die korrekte Antwort auf die oben gestellte Frage.
Wir
betrachten zum Vergleich die Frage:
WELCHE
[ALLE [X LIEBT Y][Y MALT Z]]
Sie muß zu der Anwort [[ERNA KURT LISA]] führen. Die erste Teilbedingung erlaubt die Einsetzungen [[OTTO ERNA %][ERNA KURT %][ERNA WALDI %][WALDI ERNA %]] und die zweite die Einsetzungen [[% KURT LISA]]. Die Schnittmenge ist leer! Wir dürfen also die Elemente der Listen nicht auf Gleichheit untersuchen. [ERNA KURT %] besagt, daß ERNA für X und KURT für Y eingesetzt werden darf (und irgendetwas für Z). [% KURT LISA] besagt, daß KURT für Y und für LISA für Z eingesetzt werden darf (und irgendetwas für X). Der Joker % kann durch irgendein Subjekt oder Objekt ersetzt werden. Wenn wir im ersten Tripel als Objekt LISA und im zweiten als Subjekt ERNA einsetzen, erhalten wir mit [ERNA KURT LISA] eine Lösung der Aussageform ALLE [[X LIEBT Y][Y MALT Z]].
Das folgende Programm BEIDES liefert zu zwei Einsetzungen diejenige, die beiden genügt. Es besitzt eine gewise ähnlichkeit zu PASST:
PR
BEIDES :S :T :XYZ
WENN ALLE? :S = [] :T = [] DANN RG
:XYZ
WENN EINES? :S = [] :T = [] DANN RG []
WENN
(ER :S) = (ER :T) DANN ...
... RG BEIDES OE :T
OE
:S (ML ER
:S
:XYZ)
WENN (ER :S) = "$ DANN ...
... WENN
NICHT EL? ER :T :XYZ DANN ...
... RG BEIDES OE :T
OE
:S (ML ER
:T
:XYZ)
WENN (ER :T) = "$ DANN ...
... WENN
NICHT EL? ER :S :XYZ DANN ...
... RG BEIDES OE :T
OE
:S (ML ER
:S
:XYZ)
RG []
ENDE
Welche Bedeutung haben die Programmteile
...
WENN NICHT EL? ER :T :XYZ DANN ...
... WENN NICHT EL? ER :S :XYZ
DANN ... ?
Anleitung:
überlege, welche Ausgabe das System nach der Eingabe
PSST!
[KURT MALT LISA]
PSST!
[OTTO MALT OTTO]
WELCHE
[X MALT Y]
liefern
sollte.
Gib
den Text ein, und teste das Programm BEIDES
durch:
BEIDES
[OTTO LISA %] [% LISA KURT] []
BEIDES
[% LISA %] [PAUL % %] []
BEIDES
[KURT ERNA %] [KURT LISA %] []
Wir
ändern nun das Programm SCHNITT
ab. Es soll nicht mehr die
Schnittmenge zweier Listen liefern, sondern die Menge der möglichen
Ergänzungen. Zum Beispiel soll der Aufruf
SCHNITT
[[OTTO % %][PAUL LISA %]] [[%
LISA %][% ERNA KURT]]
das
Ergebnis
[[OTTO LISA %][OTTO ERNA KURT] [PAUL LISA %]]
liefern. Das Programm SCHNITT muß jedes Element der ersten Liste mit jedem Element der zweiten Liste auf Verträglichkeit hin untersuchen und die Vereinungsmenge aller möglichen Ergänzungen bilden und zurückgeben. Also:
VERGISS
SCHNITT
PR SCHNITT :A :B
WENN :A = :B DANN RG
[]
RG VEREINIGUNG ...
... (ERGAENZUNGEN ER :A :B)
...
... (SCHNITT OE :A :B)
ENDE
PR
ERGAENZUNGEN :E :B
WENN :B = [] DANN RG
[]
SETZE "XYZ BEIDE´S :E ER :B
PRUEFE
:XYZ = []
WW RG ERGAENZUNGEN :E OE :B
WF
RG MIT :XYZ (ERGAENZUNGEN :E OE :B)
ENDE
Gib
diese Programmtexte ein, und teste wieder:
ALLE
[X LIEBT Y][Y MALT X]]
Probiere
auch:
EINES
[[X LIEBT Y][X MALT Y]]
Ja, ein Programm, das mehrere Aussagen durch oder verknüpft existiert bereits!
Wir wollen Aussagen und Aussageformen, die durch ALLE- bzw. EINES verknüpft sind, auch in den Eingaben von WELCHE und STIMMT? verwenden. Wir brauchen dazu nur das WELCHE-Programm zu erweitern:
PR
WELCHE :S
SETZE "GEPRUEFT []
WENN
ER :S = "EINES DANN RG EINES OE :S
WENN ER :S =
"ALLE DANN RG ALLE OE :S
RG SUCHE :S
ENDE
Nimm
diese änderung vor, und prüfe das Ergebnis der
Fragen:
WELCHE
[ALLE [X LIEBT Y][Y LIEBT X]]
STIMMT? [ALLE [X LIEBT
Y][Y LIEBT X]]
Nur
eine geringfügige Erweiterungen ist erforderlich, wenn es
möglich sein soll, daß ALLE-
und EINES-Fragen
auch ineinander geschachtelt werden, z.B.:
WELCHE
[ALLE [X LIEBT Y] [EINES
[Y LIEBT X][X MALT Y]]]
Füge
als erste Anweisung im Programm SUCHE
ein:
WENN
EL? ER :S [EINES ALLE] DANN ...
... RG WELCHE :S
Stelle fest, wen das System findet, wenn du die genannte Frage stellst.
Die
EINES-
und ALLE-Formulierungen
können auch in Schlußregeln benutzt werden. Gib z.B.
ein:
SCHLIESSE
[X LIEBT Y] ...
... [ALLE [X MALT Y][EINES ...
... [ALLE [X
MAENNLICH][Y WEIBLICH] ...
... [ALLE [X WEIBLICH][Y MAENNLICH]]]
Gib
nun ein:
PSST!
[ERNA WEIBLICH]
PSST! [LISA WEIBLICH]
PSST!
[OTTO MAENNLICH]
PSST!
[KURT MAENNLICH]
WELCHE [X LIEBT Y]
Auch
die Transitivität einer Beziehung können wir jetzt
beschreiben. Wenn a kleiner ist als b und b kleiner als c, dann ist a
kleiner als c. Gib ein:
SCHLIESSE [X KLEINER
Y] [ALLE [X KLEINER Z][Z KLEINER Y]]
PSST! [ERNA
KLEINER LISA]
PSST! [KURT KLEINER OTTO]
PSST!
[LISA KLEINER KURT]
WELCHE [X KLEINER Y]
Noch enthält unser System einern Fehler. Du mußt die Programmausführung mit CTRL-G stoppen. Bei der Suche nach Einsetzungen für [X KLEINER Y] findet das System zunächst [ERNA LISA %], [KURT LISA %] und [LISA KURT %]. Es sucht dann alle Einsetzungen für [ALLE [X KLEINER Z][Z KLEINER Y]], also zunächst für [X KLEINER Z]. Das liefert die Lösungen [ERNA % LISA], [KURT % OTTO] und [LISA % KURT]. Die Schlußregel anwendend, sucht das System anschließend nach allen Einsetzungen für [ALLE [X KLEINER Z][Z KLEINER Z]. Wieder schließt sich ein Kreis: Jede Anwendung der Regel erzwingt eine erneute Anwendung der Regel. Die Variable GEPRUEFT versagt in diesem Fall ihre Hilfe, weil sie bei jedem Start des WELCHE-Programms initialisiert werden muß. Wir führen darum ein zweites Abbruchskriterium ein: Wir zählen die Aufrufe des WELCHE-Programms und brechen die Suche nach z.B. drei Wiederholungen ab. Natürlich muß die Zählvariable außerhalb des Programms WELCHE auf einen Anfangswert gesetzt werden. Um die Benutzeroberfläche nicht zu verändern, benennen wir das Programm WELCHE in WELCHE1 um und führen ein neues, vorgeschaltetetes Pogramm WELCHE ein:
PR
WELCHE :S
SETZE "N :N + 1
WENN :N
> 3 DANN RG []
SETZE "GEPRUEFT []
WENN
ER :S = "EINES DANN RG EINES OE :S
WENN ER :S =
"ALLE DANN RG ALLE OE :S
RG SUCHE :S
ENDE
PR
WELCHE :S
SETZE "N 0
RG WELCHE1
:S
ENDE
Nimm
diese änderung vor, und probiere noch einmal:
WELCHE
[X KLEINER Y]
Aufgabe
über
die Relationen =, <, >, = und = wissen wir:
x
= y <=> y = x,
x < y <=> y > x,
x > y <=>
y < x,
x = z und z = y => x = y,
x < z und z < y =>
x < y,
x > z und z > y => x > y,
x = y <=>
x < y oder x = y,
x = y <=> x > y oder x = y,
x = y
<=> x = y und x > y.
Gib
diese Schlußregeln und einige Informationen ein, zum
Beispiel:
PSST!
[A < B]
PSST!
[B = E]
PSST! [E = H]
WELCHE [X = Y]
Begründe,
warum in diesem Fall nicht nur die Lösung [B
E %], sondern –
völlig korrekt – auch [B
B E] und [E
E B] erkannt
werden. Warum sollten die Folgerungen
x
< z und z < y => x < y,
x
> z und z > y => x > y
durch
x
< z und z = z1 und z1 < y => x < y,
x
> z und z = z1 und z1 > y => x > y
ersetzt werden.
?
?
? ? ? ? ? ? ? ?
durch
x < z und z = y => x <
y,
x > z und z = y => x >
y
ergänzt werden?
Aufgabe
über Vierecke wissen wir: Wenn sich die Diagonalen halbieren, dann ist das Viereck ein ... Wenn die Diagonalen sich halbieren und gleich lang sind, dann ist das Viereck ein ... Wenn die Diagonalen sich halbieren und senkrecht aufeinander stehen, dann ist das Viereck ein ... Wenn sich die Diagonalen halbieren und gleich sind und senkrecht aufeinander stehen, dann ist das Viereck ein ... Wenn alle Innenwinkel gleich groß sind, dann ist das Viereck ein ... Wenn alle Seiten gleich lang sind, dann ist das Viereck ein ... Wenn das Viereck ein Parallelogramm oder ein Rechteck oder ein Rhombus oder ein Quadrat ist, dann ... die Diagonalen. Wenn das Viereck ein Rechteck oder ein Quadrat ist, dann ... die Diagonalen ... Wenn das Viereck ein Rhombus oder ein Quadrat ist, dann .. die Diagonalen ... Wenn das Viereck ein Rechteck oder ein Quadrat ist, dann hat es ... Wenn das Viereck ein Rechteck oder ein Rhombus ist, dann hat es ...
Fülle die Lücken aus. Gib die Schlußregeln dann in unser Informationssystem ein. Nenne die Beziehungen VIERECK, PARALLELOGRAMM, RECHTECK, RHOMBUS, QUADRAT, DHALBIERT, DSENKRECHT, DGLEICHLANG, SGLEICHLANG, WGLEICHGROSS. Schreibe zum Beispiel:
PSST!
[ABCD DHALBIERT]
SCHLIESSE [X RHOMBUS] [ALLE [X
DHALBIERT][X DSENKRECHT]]
WELCHE [X RHOMBUS]
Aufgabe
über Verwandschaftbeziehungen wissen wir:
(y
ist Vater von x) oder (y ist Mutter von y) =>
x
ist Kind von y,
(y
ist Kind von x) und (x ist männlich) =>
x
ist Vater von y,
(y
ist Kind von x) und (x ist weiblich) =>
x
ist Mutter von y,
(x
ist Kind von z) und (y ist Kind von z) =>
x
ist Geschwister von y,
(x
Geschwister von y) und (x ist weiblich) =>
x
ist Schwester von y,
(x
ist Geschwister von y) und (x ist männlich) =>
x
ist Bruder von y,
(x
ist Kind von y) oder (y ist Kind von x) oder (x ist Geschwister von
y) oder ((x ist verwandt mit z) und (z ist verwandt mit y))
=>
x ist
verwandt mit y.
Gib entsprechend Schlußfolgerungen für die Verwandtschaftsbeziehungen Ehemann (Gatte), Ehefrau (Gattin), Schwager, Schwägerin, Großvater (Opa), Großmutter (Oma), Onkel, Tante, Neffe, Nichte, Vorfahr, Nachkomme an.
Starte
das Informationssystem durch INIT
neu und gib einige
dieser Schlußregeln in der Form
SCHLIESSE
[X VATERVON Y] [ALLE [X KINDVON Y][X MAENNLICH]]
ein.
Füge einige Informationen hinzu, z.B.:
PSST!
[CLIFF BRUDERVON PAMELA]
Prüfe
dann, ob das Informationssystem korrekt arbeitet:
WELCHE
[X VERWANDTMIT J.R.]
Aufgabe
Wie läßt sich ein NICHT-Operator realisieren? überlege zunächst, welches Ergebnis der Aufruf
WELCHE [NICHT [X LIEBT Y]] liefern sollte.