Wie schreibt man eine Regel in Prolog?
Eine Regel in Prolog sagt: Etwas gilt, wenn etwas anderes gilt. So lassen sich aus wenigen Fakten viele neue Aussagen ableiten, etwa „Großeltern“ aus „Eltern“.
Eine Regel darf sich auch selbst benutzen. Damit beschreiben Sie in zwei Zeilen alle Vorfahren eines Menschen, egal wie viele Generationen es sind.
Am Ende dieser Lektion
Notiz
Ich kann eine Regel in Prolog lesen, die andere Fakten benutzt, auch eine, die sich selbst aufruft.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Regel | eine Aussage der Form: Dies gilt, wenn jenes gilt |
| Kopf | die linke Seite einer Regel, das, was sie festlegt |
| Rumpf | die rechte Seite einer Regel, die Bedingungen |
| Rekursion | eine Regel, die sich selbst aufruft |
| Basisfall | die Regel ohne Selbstaufruf, bei der die Suche endet |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Eine Regel macht aus Fakten neue Aussagen
Eine Regel hat einen Kopf und einen Rumpf, getrennt durch :-. Lesen Sie das Zeichen als „wenn“. Der Kopf gilt, wenn der ganze Rumpf gilt. Ein Komma im Rumpf heißt „und“.
Beispiel: Wer Elternteil eines Elternteils ist, ist Großelternteil. Variablen verbinden die Teile: Das mittlere Y muss in beiden Fakten derselbe Wert sein.
Eine Regel für Großeltern
% Beispiel: X ist Großelternteil von Z, wenn
% X Elternteil von Y ist und Y Elternteil von Z.
grosselternteil(X, Z) :- elternteil(X, Y), elternteil(Y, Z).Die Regeln des Labs ansehen
docker exec prolog cat family.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Wie Prolog die Großeltern von eve findet
| Schritt | Prolog prüft | Ergebnis |
|---|---|---|
| 1 | parent(Y, eve) in den Fakten suchen | Y ist ben |
| 2 | parent(X, ben) mit diesem Y suchen | X ist tom |
| 3 | Beide Teile des Rumpfs gelten | grandparent(tom, eve) gilt |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Wer ist Großelternteil von eve?
docker exec prolog swipl -q -g "forall(grandparent(X, eve), (write(X), nl))" -t halt family.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein Komma bedeutet und
docker exec prolog swipl -q -g "forall((parent(tom, K), parent(K, E)), (write(K/E), nl))" -t halt facts.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Eine Regel darf sich selbst aufrufen
Ein Vorfahre ist ein Elternteil oder ein Vorfahre eines Elternteils. Die Regel benutzt also das, was sie erklärt. Das heißt Rekursion.
Zwei Regeln genügen. Die erste, der Basisfall, sagt: Ein Elternteil ist ein Vorfahre. Die zweite sagt: Wer einen Elternteil hat, der selbst Vorfahre ist, hat diesen Vorfahren auch.
Alle Nachkommen von tom ausgeben
docker exec prolog swipl -q -g "forall(ancestor(tom, Z), (write(Z), nl))" -t halt family.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Dieselbe Idee mit eigenen Namen
% Beispiel: Basisfall, dann der Schritt eine Generation weiter.
vorfahre(X, Y) :- elternteil(X, Y).
vorfahre(X, Y) :- elternteil(X, Z), vorfahre(Z, Y).Beispiel: ancestor(tom, eve) Schritt für Schritt
| Aufruf | Regel | Neue Frage |
|---|---|---|
| ancestor(tom, eve) | Basisfall: parent(tom, eve)? | Nein, kein solcher Fakt |
| ancestor(tom, eve) | Zweite Regel: parent(tom, Z), Z ist ann | ancestor(ann, eve)? |
| ancestor(ann, eve) | Weder Basisfall noch Kinder von ann führen zu eve | Nein, zurück |
| ancestor(tom, eve) | Zweite Regel noch einmal: Z ist ben | ancestor(ben, eve)? |
| ancestor(ben, eve) | Basisfall: parent(ben, eve) | Ja, fertig |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Rückwärts fragen: wer ist Vorfahre?
docker exec prolog swipl -q -g "forall(ancestor(A, eve), (write(A), nl))" -t halt family.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein häufiger Fehler
Warnung
Viele denken, eine Regel sei eine Funktion mit festem Eingang und Ausgang. Eine Regel beschreibt eine Beziehung. Sie können beide Seiten offen lassen: ancestor(tom, Z) fragt nach Nachkommen, ancestor(A, eve) nach Vorfahren, dieselbe Regel in beide Richtungen.
Ein Nein bei der Rekursion
docker exec prolog swipl -q -g "( ancestor(cat, tom) -> writeln(ja) ; writeln(nein) )" -t halt family.plHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Vorfahren in Python suchen
Prologs Rekursion lässt sich in Python nachbauen. Die Fakten sind eine Liste von Paaren: Elternteil zuerst, Kind danach. Sie schreiben vier Funktionen.
eltern_von und nachkommen durchsuchen die Liste, vorfahren und ist_vorfahre rufen sich oder ihre Nachbarn rekursiv auf. Der Basisfall ist: Ein Mensch ohne Eltern hat keine Vorfahren.