为什么这个prolog程序会导致无限递归?

时间:2011-10-21 15:01:01

标签: prolog stack-overflow

我正在努力建立一个简单的知识库。但是,我正在努力让类别系统发挥作用。

到目前为止,这是该计划:

subset(tomatoes, fruits).
subset(fruits, food).
subset(X, Z) :- subset(X, Y), subset(Y, Z), not(X==Y), not(Y==Z), not(X==Z).
member(X, Z) :- member(X, Y), subset(Y, Z).
member(t1, tomatoes).

查询:

member(t1,tomatoes).
ERROR: Out of local stack
   Exception: (1,765,494) member(t1, _G28504) ? abort
% Execution Aborted

1 个答案:

答案 0 :(得分:4)

您遇到了名为 left recursion 的现象。解决目标subset(X, Z)会减少为使用新的未绑定变量subset(X, Y)解决目标Y,这会导致无限制地解决同一目标subset(X, Z)等问题。应避免左递归。

通常的方法是在基本事实和传递闭包规则之间进行dinstinguish。你可以尝试:

subset1(tomatoes, fruits).
subset1(fruits, food).

subset(X, Y) :- subset1(X, Y).
subset(X, Z) :- subset1(X, Y), subset(Y, Z).

member1(t1, tomatoes).
member1(t2, tomatoes).

member(X, Y) :- member1(X, Y).
member(X, Z) :- member1(X, Y), subset(Y, Z).

?- member(t1, food).       ===> TRUE

此配方中没有左递归。首先尝试一个可以终止递归的直接事实。只有在没有事实的情况下,才会执行递归调用。