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 Programm psst! 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 ist thing :prädikat gleichbedeutend mit thing "ruft, und das ist :ruft.

  • Es gibt eine weitere Aussage: psst! [erna liebt kurt]
    Im Programm psst! 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 #]
  stimmt? [# liebt kurt]
  stimmt? [# liebt #]
  stimmt? [erna # kurt]
Hoppla, da stimmt etwas nicht!

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]
  :prädikate
  alle_sätze :prädikate
Und dann
  stimmt? [# liebt kurt]
  stimmt? [# liebt #]
  stimmt? [erna # kurt]

Kleine Ergänzungen

Die Raute # als Joker ist nicht schön. Klangvoller sind Sätze wie
  stimmt? [jemand liebt kurt]
  stimmt? [jemand liebt jemanden]
  stimmt? [erna etwas kurt]
oder 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 durch make "zeichen last last :eingabe ermittelt.
  • Je nachdem, ob :zeichen ein Punkt oder ein Fragezeichen ist, wird das Programm psst! oder das Programm stimmt? gestartet.
  • Als Parameter erwarten psst! und stimmt? einen Satz ohne Punkt oder Fragezeichen am Ende. Diesen um das letzte Zeichen des letzten Wortes gekürzten Satz erhält man mit
    lput butlast last :eingabe butlast :eingabe
  • Wenn das letzte Zeichen der Eingabe weder ein Punkt noch ein Fragezeichen ist, gibt tratsch die Antwort wie 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.

Die Antwort des Computers soll lauten:
[[erna % %]]
[[% % kurt] [% % waldi]]
[[otto % erna] [erna % kurt] [erna % waldi]]
[]
Das könnte später verkürzt werden zu:
[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]
Make "RUFT [[otto ruft erna]]
Make "LIEBT [[erna liebt kurt] [erna liebt waldi] [waldi liebt erna]]
Make "MALT [[kurt malt lisa]]
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.

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 #]
ja
In der wohlklingen Version
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.