我正在努力建立一个简单的知识库。但是,我正在努力让类别系统发挥作用。
到目前为止,这是该计划:
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
答案 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
此配方中没有左递归。首先尝试一个可以终止递归的直接事实。只有在没有事实的情况下,才会执行递归调用。