Rekursion in Prolog

Prädikate können rekursiv definiert werden, d.h. in einem Prädikat kann es selbst wieder auftauchen

% Rekursionsanker: Eltern sind direkt Vorfahren
ancestor(A,B) :- parent(A,B).

% Rekursionsschritt: Vorfahren können beliebig viele Generationen entfernt sein
ancestor(A,B) :- parent(A,A_B), ancestor(A_B,B).

Prolog wird das Prädikat so oft in sich selbst einsetzen bis eine gültige Belegung gefunden ist.

Regeln für Rekursion

Nicht-Rekursive Klauseln zuerst!

Innerhalb einer Klausel: Nicht-rekursive Literale vor rekursivem Literal!

Zyklen in den Daten (Graph):

Datenaustausch zwischen Rekursionsschritten

Wenn zwischen den Rekursionsschritten Datenaustausch nötig ist, kann dies über Variablen geschehen.

cntAncestor(A,B,Cnt,Erg) :- parent(A,B), Erg = Cnt.
cntAncestor(A,B,Cnt,Erg) :- parent(A,A_B), Cnt1 is Cnt+1,
                            cntAncestor(A_B,B,Cnt1,Erg).

Anfrage:

?- cntAncestor(shmi, luke, 1, Erg).
Erg = 2

Alternative Umsetzung der Rekursion

Setzen des Startwerts für Erg im Rekursionsanker.

cntAncestor2(A,B,1) :- parent(A,B).
cntAncestor2(A,B,Erg) :- parent(A,A_B),
                         cntAncestor2(A_B,B,Erg1), Erg is Erg1 + 1.

Anfrage:

?- cntAncestor2(shmi, luke, Erg).
Erg = 2