为什么在定义转换两个原子关系的谓词时会出现堆栈限制超出错误?

Why do i get a stack limit exceeded error when defining a predicate that convert the relation of two atoms?

我想知道为什么在这些情况下程序会无限递归:

?- 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 添加到您的程序中,我们得到了一个需要更少(或相等)推理的新程序。

<s>love(amanda, kay) :- <b>false</b></s>.
<s>love(kay, geo) :- <b>false</b></s>.
<s>love(geo, rob) :- <b>false</b></s>.
love(X, Y) :-
   love(X, Z), <b>false</b>,
   <s>love(Z, Y)</s>.
<s>love(X, Y) :-  <b>false</b></s>,
   <s>love(Y, X)</s>.

因为这个片段(称为)没有终止,你原来的程序也不会终止。如您所见,所有人员都已被删除。因此实际姓名不会影响结果。

如果你想修复交换性,而是引入一个进一步的谓词:

love2(X, Y) :- love1(X, Y).
love2(X, Y) :- love1(Y, X).

要包含传递闭包,请使用 closure/3:

love3(X, Y) :-
   closure(love2, X, Y).