我想知道为什么在这些情况下程序会无限递归:
?- love(kay, amanda).
和
?- love(rob, amanda).
这是代码:
love(amanda, kay).
love(kay, geo).
love(geo, rob).
love(X, Y) :-
love(X, Z),
love(Z, Y).
love(X, Y) :-
love(Y, X).
我想知道为什么在这些情况下程序会无限递归:
?- love(kay, amanda).
和
?- love(rob, amanda).
这是代码:
love(amanda, kay).
love(kay, geo).
love(geo, rob).
love(X, Y) :-
love(X, Z),
love(Z, Y).
love(X, Y) :-
love(Y, X).
首先,你的程序总是进入一个无限循环。无论您使用什么名称。甚至?- loves(amanda, kay).
循环。为了更好地看到这一点,不如问?- loves(amanda, kay), false.
为什么我这么确定你的程序总是循环?
要看到这一点,我们需要一些虚假的工作。通过将目标添加false
到您的程序中,我们得到了一个需要更少(或相等)推理的新程序。
love(amanda, kay) :- false.
love(kay, geo) :- false.
love(geo, rob) :- false.
love(X, Y) :-
love(X, Z), false,
love(Z, Y).
love(X, Y) :- false,
love(Y, X).
因为这个片段(称为故障切片)不会终止,所以您的原始程序不会终止。如您所见,所有人员都已被删除。因此,实际名称无法影响结果。
如果要修复交换性,请引入进一步的谓词:
love2(X, Y) :- love1(X, Y).
love2(X, Y) :- love1(Y, X).
要包括传递闭包,请使用closure/3:
love3(X, Y) :-
closure(love2, X, Y).