【问题标题】:Prolog infinite loopProlog无限循环
【发布时间】:2013-01-27 13:38:27
【问题描述】:

这是一个应该找出谁与 john 兼容的程序。 我是 Prolog 的新手。为了让Prolog知道例如。遇见(X,Y)=遇见(Y,X) 已经写了很多代码。 现在当我开始查询时

?- compatible(john, X)

进入无限循环...

源代码:

compatible(X,Y) :- reading(X), reading(Y).
compatible(X,Y) :- football(X), football(Y).
compatible(X,Y) :- friends(X,Y).
compatible(X,Y) :- mutual(X,Y).
friends(X,Y) :- havemet(X,Y), compatible(X,Y).
havemet(X,Y) :- met(X,Y).
havemet(X,Y) :- met(Y,X).
mutual(X,Y) :- friends(X,Temp), friends(Y,Temp).
mutual(X,Y) :- friends(Temp,X), friends(Y,Temp).
mutual(X,Y) :- friends(X,Temp), friends(Temp,Y).
mutual(X,Y) :- friends(Temp,X), friends(Temp,Y).

football(john).
football(james).
friends(john, carl).
friends(carl, john).
reading(carl).
reading(fred).
reading(emily).
met(carl, emily).
met(fred, james).
met(fred, emily).

我一直在研究这么多,但我仍然不明白问题是什么以及如何解决它。能帮到我就太好了。

【问题讨论】:

  • 你的意思可能是compatible(john, X)? (大写 X)?
  • 是的,打错字了,抱歉

标签: prolog swi-prolog failure-slice b-prolog xsb


【解决方案1】:

我对你有一个无限循环并不感到惊讶。 compatible 取决于 friendsfriends 取决于 compatible。你确定这是你想要的吗?

请注意,如果您真的希望您的规则是递归的,您需要一个停止条件。但我不明白为什么你需要递归来解决像相似性匹配这样简单的问题。

【讨论】:

  • 其实,递归关系是我的一项练习的要求,但我只是想了解问题,而不是把问题扔出去让别人帮我做,无论如何非常感谢。
【解决方案2】:

您使用的是什么 Prolog 系统?您是否需要使用特定系统?

您的程序不会在标准 Prolog 中终止,而是会在带有表格支持的 Prolog 中终止,例如 XSB-Prolog http://xsb.sourceforge.net/ 或 B-Prolog http://www.probp.com/ - 只需添加 :- auto_table. 作为第一行你的程序。

| ?- compatible(john, X).
compatible(john, X).
X = john ?;
X = james ?;
X = carl ?;
X = emily ?;
no

【讨论】:

  • 对于 SWI-Prolog 添加到代码的开头::- use_module(library(tabling)). :- table friends/2, compatible/2, mutual/2, havemet/2, met/2, football/1, reading/1.
【解决方案3】:

那么你的程序有什么问题?这是一种本地化您遇到的问题的方法。通过插入目标false,我们获得了failure slice。这是一个与原始程序共享许多属性的片段。特别是:如果失败切片循环,则原始程序也会循环。因此,故障片向我们展示了程序的一部分,必须修改以克服原始问题。对于您的查询,我得到以下仍然没有终止的片段:

?- 兼容(约翰,X),兼容(X,Y):- false,读数(X),读数(Y)compatible(X,Y) :- false, football(X), football(Y)兼容(X,Y):- ,朋友(X,Y)。 兼容(X,Y):- 相互(X,Y),false。 朋友(X,Y):- havemet(X,Y),兼容(X,Y)。 朋友(约翰,卡尔):- 。 朋友(卡尔,约翰)。 havemet(X,Y) :- false,met(X,Y)。 已经满足(X,Y):- 满足(Y,X)。 mutual(X,Y) :- false,friends(X,Temp),friends(Y,Temp)。 相互(X,Y):-朋友(Temp,X),朋友(Y,Temp),false。 相互(X,Y):-朋友(X,Temp),false朋友(Temp,Y)mutual(X,Y) :- false,friends(Temp,X),friends(Temp,Y)。 遇见(卡尔,艾米丽)。 遇见(弗雷德,詹姆斯):- met(fred, emily) :-

但是对于compatible/2 的任何查询不应该终止吗?对于最一般的查询,可以进一步减少失败切片:

?- 兼容(X,Y),false兼容(X,Y):- false,读数(X),读数(Y)compatible(X,Y) :- false, football(X), football(Y)兼容(X,Y):- ,朋友(X,Y)。 兼容(X,Y):- 相互(X,Y),false。 朋友(X,Y):- havemet(X,Y),兼容(X,Y)。 朋友(约翰,卡尔):- 朋友(卡尔,约翰):- havemet(X,Y) :- false,met(X,Y)。 已经满足(X,Y):- 满足(Y,X)。 mutual(X,Y) :- false,friends(X,Temp),friends(Y,Temp)mutual(X,Y) :- false,friends(Temp,X),friends(Y,Temp)。 相互(X,Y):-朋友(X,Temp),false朋友(Temp,Y)mutual(X,Y) :- false,friends(Temp,X),friends(Temp,Y)。 遇见(卡尔,艾米丽)。 遇见(弗雷德,詹姆斯):- met(fred, emily) :-

在剩下的部分中,您必须以某种方式解决问题。可能还有其他不终止的原因。但无论如何,您必须解决这个问题。

如果这还不够好,您可以将目标V = const 添加到程序中。但我认为这应该足够了......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多