This is a hint (Hinweis) text of GUPU taken literally from the system. It's probably not very interesting reading for you.
**NEXT:To continue the guided tour go back where You came from
**NEXT:Continue reading the hints in German (...)

Dieser Hinweis ist aus der Übung im WS 1994/95 oder aus einer noch älteren Übung oder war nie Teil einer Übung und ist daher möglicherweise für spätere Übungen nicht gültig!


          Mengenausdrücke, setof/3

Die Kinder von Maria Theresia konnten wir
bisher nur als Lösungsmenge (bzw. Sequenz)
darstellen.

:- kind_von(Kind, maria_theresia).
@ Kind = joseph_II. 
@ Kind = leopold_II. 
@ Kind = marie_antoinette. 
@ 3 Lösungen gefunden

Oft möchte man die so gefundenen Lösungen
weiterverarbeiten, etwa in Listenform. Die
Lösungssequenz muß dazu endlich sein. Das
vordefinierte Prädikat setof/3 erlaubt, die
Lösungsmenge als ein Ganzes zu betrachten,
nicht nur jede Lösung für sich; um etwa die
Lösungsmenge als Liste weiterzuverwenden.

   setof(Lösungsschema, Ziel, Lösungsmenge)

Ziel
   ist z.B. kind_von(Kind, maria_theresia)
Lösungsschema
   ist ein Term, der nur Variablen aus Ziel
   enthalten sollte, und beschreibt, wie eine
   Lösung aussehen soll. Etwa hier: Kind.
Lösungsmenge ist eine sortierte Liste aller
   kopierten Instanzen von Lösung, die gefunden
   wurden.

:- setof(Kind, kind_von(Kind, maria_theresia), Kinder).
@ Kinder = [joseph_II,leopold_II,marie_antoinette]. 
@ Eine Lösung gefunden

Als Antwort erhalten wir Bindungen für
Lösungsmenge und (gelegentlich für Variablen in
Ziel, siehe unten), JEDOCH keine Bindungen für
Lösungsschema. Lösungsschema dient nur zur
Beschreibung eines Element der Lösungsmenge.

Diese Anfrage kann verallgemeinert werden, man
sieht nun nicht nur die Kinder Maria Theresias.

:- setof(Kind, kind_von(Kind, Elternteil), Kinder).
@ Elternteil = franz_I, Kinder = [joseph_II,leopold_II]. 
@ Elternteil = karl_VI, Kinder = [maria_theresia]. 
@ Elternteil = leopold_I, Kinder = [joseph_I,karl_VI]. 
@ Elternteil = leopold_II, Kinder = [franz_II]. 
@ Elternteil = maria_theresia, Kinder = [joseph_II,leopold_II,marie_antoinette]. 
@ 5 Lösungen gefunden

Der obigen Anfrage entspricht:
   Wer hat welche Kinder?

Umgekehrt kann man ebenso fragen:
   Wer hat welche Eltern?

:- setof(Elternteil, kind_von(Kind, Elternteil), Eltern).
@ Eltern = [leopold_II], Kind = franz_II. 
@ Eltern = [leopold_I], Kind = joseph_I. 
@ Eltern = [franz_I,maria_theresia], Kind = joseph_II. 
@ Eltern = [leopold_I], Kind = karl_VI. 
@ Eltern = [franz_I,maria_theresia], Kind = leopold_II. 
@ 5 Lösungen gefunden

Eine ähnliche Anfrage wäre:
   Welche Kinder?

kind(Kind) :-
	kind_von(Kind, _Elternteil).

:- kind(Kind).
@ Kind = joseph_I. 
@ Kind = karl_VI. 
@ Kind = maria_theresia. 
@ Kind = joseph_II. 
@ Kind = joseph_II.  % Redundant 
@ Kind = leopold_II. 
@ Kind = leopold_II.  % Redundant 
@ Kind = marie_antoinette. 
@ Kind = franz_II. 
@ 9 Lösungen gefunden, davon 2 redundant

:- setof(Kind, kind(Kind), L).
@ L = [franz_II,joseph_I,joseph_II,karl_VI,leopold_II,maria_theresia,marie_antoinette]. 
@ Eine Lösung gefunden

Man sieht in diesem Falle: Die Liste enthält
keine Duplikate, die einfache Anfrage aber
schon.

Bei vielen Anfragen müßte man sich eigens ein
Hilfsprädikat wie kind/1 definieren. Denken Sie
an die Weltkarte mit ihren zahllosen Argumenten
und Kombinationsmöglichkeiten! In der
Definition von kind/1 ist _Elternteil eine
existentielle Variable. Man kann in einem Ziel
derartige Variablen wie folgt explizit
existentiell quantifizieren:
      V1^V2^ZielmitV1undV2
Dadurch ist das Hilfsprädikat nicht mehr nötig.

:- setof(Kind, Elternteil^kind_von(Kind, Elternteil), L).
@ L = [franz_II,joseph_I,joseph_II,karl_VI,leopold_II,maria_theresia,marie_antoinette]. 
@ Eine Lösung gefunden

Wird Kind existentiell quantifiziert, erhält
man die Liste aller Eltern:

:- setof(Elternteil, Kind^kind_von(Kind, Elternteil), Eltern).
@  Eltern = [franz_I,karl_VI,leopold_I,leopold_II,maria_theresia]. 
@ Eine Lösung gefunden

Und nun eine geschachtelte Verwendung:
Die Liste aller Paare Eltern und ihrer Kinder

:- setof(Elternteil-Kinder, setof(Kind, kind_von(Kind, Elternteil), Kinder), EKs).
@ EKs = [franz_I-[joseph_II,leopold_II],karl_VI-[maria_theresia],leopold_I-[joseph_I,karl_VI],leopold_II-[franz_II],maria_theresia-[joseph_II,leopold_II,marie_antoinette]]. 
@ Eine Lösung gefunden

Hier ist -/2 eine Struktur, sie wird häufig für
Paare gebraucht. Man hätte natürlich auch eine
x-beliebige andere Struktur verwenden können.

:- setof(k(Kind), kind_von(Kind, maria_theresia), Kinder).
@ Kinder = [k(joseph_II),k(leopold_II),k(marie_antoinette)]. 
@ Eine Lösung gefunden

Wieviele Kinder Maria Theresias sind bekannt?
(Wenn sie überhaupt welche hat)

:- setof(Kind, kind_von(Kind, maria_theresia), Kinder), length(Kinder, Kinderzahl).
@ Kinder = [joseph_II,leopold_II,marie_antoinette], Kinderzahl = 3. 
@ Eine Lösung gefunden

Gibt es überhaupt keine Lösung, so scheitert
jedoch setof/3. Folgene Frage ist also NICHT so
direkt möglich bzw. sinnvoll!

Wieviele Kinder Marie-Antoinettens sind bekannt?

:/- setof(Kind, kind_von(Kind, marie_antoinette), Kinder), length(Kinder, Kinderzahl).
Die Antwort ist also nicht 0!
:/- kind_von(Kind, marie_antoinette).

Man kann dies nun verallgemeinern.

anzahl(Lösungsschema, Pred, Zahl) :-
	setof(Lösungsschema, Pred, Lösungen),
	length(Lösungen, Zahl).

:- anzahl(Kind, kind_von(Kind, Elternteil), Kinderzahl).
@ Elternteil = franz_I, Kinderzahl = 2. 
@ Elternteil = karl_VI, Kinderzahl = 1. 
@ Elternteil = leopold_I, Kinderzahl = 2. 
@ Elternteil = leopold_II, Kinderzahl = 1. 
@ Elternteil = maria_theresia, Kinderzahl = 3. 
@ 5 Lösungen gefunden

Vielleicht ist jetzt auch klar, warum setof/3
scheitert und nicht die leere Liste liefert,
wenn das Ziel nicht erfüllt ist. (Erinnern Sie
sich an die Negationsgeschichten?) Die
folgenden Antworten sollten ja sonst auch
gefunden werden. Diesmal nicht nur 27,
almwiese, sondern auch sämtliche Päpste. Die
untenstehenden Antworten sind also frei
erfunden!

:- anzahl(Kind, kind_von(Kind, Elternteil), Kinderzahl).
@ Elternteil = 27, Kinderzahl = 0.
@ Elternteil = almwiese, Kinderzahl = 0.
@ Elternteil = donau, Kinderzahl = 0.
@ Elternteil = franz_I, Kinderzahl = 2.
@ Elternteil = johannes_I, Kinderzahl = 0. 
@ Elternteil = johannes_II, Kinderzahl = 0. 
@ Elternteil = johannes_III, Kinderzahl = 0. 
@ Elternteil = johannes_IV, Kinderzahl = 0. 
@ Elternteil = johannes_V, Kinderzahl = 0.
@ ...
@ Elternteil = johannes_XXII, Kinderzahl = 0.
@ Elternteil = johannes_XXIII, Kinderzahl = 0.
@ Elternteil = karl_VI, Kinderzahl = 1.
@ Elternteil = leopold_I, Kinderzahl = 2. 
@ Elternteil = leopold_II, Kinderzahl = 1.
@ Elternteil = marie_antoinette, Kinderzahl = 0.
@ Elternteil = maria_theresia, Kinderzahl = 3.
@ Elternteil = prolog, Kinderzahl = 0.
@ Anfrage unterbrochen, Antwort unvollständig

setof/3 kann auch verwendet werden, um
redundante Lösungen eines Ziels auszuschließen.
Das Lösungsschema interessiert uns hier gar
nicht, deshalb das Atom t (oder sonst ein
Grundterm).

:- setof(t, Elternteil^kind_von(Kind,Elternteil), L).
@ Kind = franz_II, L = [t]. 
@ Kind = joseph_I, L = [t]. 
@ Kind = joseph_II, L = [t]. 
@ Kind = karl_VI, L = [t]. 
@ Kind = leopold_II, L = [t]. 
@ Kind = maria_theresia, L = [t]. 
@ Kind = marie_antoinette, L = [t]. 
@ 7 Lösungen gefunden

(Haben Sie das alles bis hierhin gelesen und
verstanden? Schaun Sie sich die Weltkarte dazu
an! Und: Sie können ja stets Fragen stellen!)

        \hinweis{PrologAllgemein}
Zurück: \hinweis{init}

**NEXT:To continue the guided tour go back where You came from
**NEXT:Continue reading the hints in German