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

发布于 2024-12-11 08:47:19 字数 437 浏览 0 评论 0原文

我正在尝试制作一个简单的知识库。然而,我正在努力让类别系统发挥作用。

这是到目前为止的程序:

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

I am trying to make a simple knowledge base. However, I'm struggling getting the category system to work.

Here is the program so far:

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).

Query:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少女情怀诗 2024-12-18 08:47:19

您遇到了名为左递归的现象。解决目标 subset(X, Z) 被简化为使用新的未绑定变量 Y 来解决目标 subset(X, Y),并且这个导致无限地解决相同的目标subset(X, Z)等。应避免左递归。

通常的方法是区分基本事实和传递闭包的规则。你可以尝试:

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

这个公式中没有左递归。首先尝试可以终止递归的直接事实。仅当没有事实时,才执行递归调用。

You encountered the phenomenon called left recursion. Solving the goal subset(X, Z) is reduced to solving the goal subset(X, Y) with a new unbound variable Y and this leads to solving the same goal subset(X, Z) etc, ad infinitum. Left recursions should be avoided.

The usual approach is to dinstinguish between basic facts and rules for transitive closures. You could try:

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

There is no left recursion in this formulation. First a direct fact is tried that can terminate the recursion. Only if there is no fact, a recursive call is performed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文