Recursion prolog中递归的停止条件

Recursion prolog中递归的停止条件,recursion,prolog,transitive-closure,Recursion,Prolog,Transitive Closure,以下是我知识库中的事实((递归练习2)): 现在我想用递归来推断一些明显的东西,“bob”比“george”高 我尝试添加此规则以解决此问题: taller(X,Y) :- taller(X,Z),taller(Z,Y). 我需要您的帮助为这个递归设置一个停止条件,因为现在我有一个堆栈溢出错误: | ?- taller(bob,george). Fatal Error: local stack overflow (size: 8192 Kb, environment variable use

以下是我知识库中的事实((递归练习2)):

现在我想用递归来推断一些明显的东西,“bob”比“george”高

我尝试添加此规则以解决此问题:

taller(X,Y) :- taller(X,Z),taller(Z,Y).
我需要您的帮助为这个递归设置一个停止条件,因为现在我有一个堆栈溢出错误:

| ?- taller(bob,george).

Fatal Error: local stack overflow (size: 8192 Kb, environment variable used: LOCALSZ)

谢谢

问题在于递归的
谓词/2
被定义为:

taller(X,Y) :-
    taller(X,Z),
    taller(Z,Y).
因此,一个
higher/2
谓词始终可以在“调用堆栈”上生成两个新的
higher/2
谓词,这种嵌套可以继续下去

处理这个问题的一种方法是将知识与传递闭包分离。通过定义一个
is_higher/2
谓词,该谓词计算
higher/2
谓词的传递闭包,如下所示:

is_taller(X,Y) :-
    taller(X,Y).
is_taller(X,Y) :-
    taller(X,Z),
    is_taller(Z,Y).
现在可以说是“保证进度”,因为每次调用
更高/2
时,它都会调用
更高/2
。由于
higher/2
没有递归,因此可能的答案数量是有限的。由于
higher/2
是一个严格的顺序关系,最终我们将到达最短的人,因此回溯将耗尽

因此,完整的代码应该是:

taller(bob,mike).   % bob is taller than mike
taller(mike,jim).   % mike is taller than jim
taller(jim,george). % jim is taller than george

is_taller(X,Y) :-
    taller(X,Y).
is_taller(X,Y) :-
    taller(X,Z),
    is_taller(Z,Y).
个子更高(鲍勃、迈克)。%鲍勃比迈克高
高一点(迈克,吉姆)。%迈克比吉姆高
高一点(吉姆,乔治)。%吉姆比乔治高
_是否更高(X,Y):-
更高(X,Y)。
_是否更高(X,Y):-
更高(X,Z),
更高(Z,Y)。
taller(bob,mike).   % bob is taller than mike
taller(mike,jim).   % mike is taller than jim
taller(jim,george). % jim is taller than george

is_taller(X,Y) :-
    taller(X,Y).
is_taller(X,Y) :-
    taller(X,Z),
    is_taller(Z,Y).