Порядок предложений и целей
Логически непротиворечивое определение предиката может быть процедурно неправильно. Вызов
?- p.
предиката, определенного правилом
p :- p,
приводит к бесконечному циклу.
Рассмотрим различные варианты программы "родственные отношения", полученные путем переупорядочивания предложений и целей.
parent(pam,bob).
parent(tom,bob).
parent(tom,lis).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
Вариант 1.
predok(X,Y) :-
parent(X,Y).
predok(X,Y) :-
parent(X,Z),
predok(Z,Y).
Трассировка запроса:
?- predok (tom,pat)
дает следующую последовательность выполнения.
Call: ( 7) parent(tom, pat)
Fail: ( 7) parent(tom, pat)
Call: ( 7) parent(tom, L384), predok(L384, pat)
Call: ( 8) parent(tom, L384)
Exit: ( 8) parent(tom, bob)
Call: ( 9) parent(bob, pat)
Exit: ( 9) parent(bob, pat)
Exit: ( 7) parent(tom, bob), predoc(bob, pat)
Yes
Вариант 2.
pred2(X,Z):-
parent(X,Y),
pred2(Y,Z).
pred2(X,Z):-
parent(X,Z).
Трассировка запроса:
?- pred2 (tom,pat)
показывает более продолжительную последовательность выполнения.
Call: ( 7) parent(tom, L384),predok(L384, pat)
Call: ( 8) parent(tom, L384)
Exit: ( 8) parent(tom, bob)
Call: ( 9) parent(bob, L520), predok(L520, pat)
Call: ( 10) parent(bob, L520)
Exit: ( 10) parent(bob, ann)
Call: ( 11) parent(ann, L656), predok(L656, pat)
Call: ( 12) parent(ann, L656)
Fail: ( 12) parent(ann, L656)
Fail: ( 11) parent(ann, L656), predok(L656, pat)
Call: ( 11) parent(ann, pat)
Fail: ( 11) parent(ann, pat)
Exit: ( 10) parent(bob, pat)
Call: ( 11) parent(pat, L612), predok(L612, pat)
Call: ( 12) parent(pat, L612)
Exit: ( 12) parent(pat, jim)
Call: ( 13) parent(jim, L704), predok(L704, pat)
Call: ( 14) parent(jim, L704)
Fail: ( 14) parent(jim, L704)
Fail: ( 13) parent(jim, L704) ,predok(L704, pat)
Call: ( 13) parent(jim, pat)
Fail: ( 13) parent(jim, pat)
Fail: ( 11) parent(pat, L612), predok(L612, pat)
Call: ( 11) parent(pat, pat)
Fail: ( 11) parent(pat, pat)
Fail: ( 9) parent(bob, L520) , predok(L520, pat)
Call: ( 9) parent(bob, pat)
Exit: ( 9) parent(bob, pat)
Exit: ( 7) parent(tom, bob, pat)
Yes
Программа работает правильно, но не эффективно.
Вариант 3.
pred3(X,Z):-
parent(X,Z).
pred3(X,Z):-
pred3(X,Y),
parent(Y,Z).
Этот вызов благополучно вычисляется
?- pred3(tom,pat).
Call: ( 7) parent(tom, pat)
Fail: ( 7) parent(tom, pat)
Call: ( 7) predok(tom, L384), parent(L384, pat)
Call: ( 9) parent(tom, L384)
Exit: ( 9) parent(tom, bob)
Call: ( 8) parent(bob, pat)
Exit: ( 8) parent(bob, pat)
Exit: ( 7) predok(tom, bob), parent(bob, pat)
Yes