3

这是一个应该找出谁与 john 兼容的程序。我是 Prolog 的新手。为了让Prolog知道例如。met(X,Y) = met (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).

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

4

3 回答 3

2

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

?- 兼容(约翰,X),兼容(X,Y):-,阅读(X),阅读(Y)兼容(X,Y):-,足球(X),足球(Y)兼容(X,Y):-,朋友(X,Y)。
兼容(X,Y):- 相互(X,Y),。

朋友(X,Y):- havemet(X,Y),兼容(X,Y)。
朋友(约翰,卡尔):-。
朋友(卡尔,约翰)。

havemet(X,Y) :- false,met(X,Y)。
已经满足(X,Y):- 满足(Y,X)。

相互(X,Y):-,朋友(X,Temp),朋友(Y,Temp)。
相互(X,Y):-朋友(Temp,X),朋友(Y,Temp),。
相互(X,Y):-朋友(X,Temp),朋友(Temp,Y)相互(X,Y):-,朋友(Temp,X),朋友(Temp,Y)。

遇见(卡尔,艾米丽)。
遇见(弗雷德,詹姆斯): -遇见(弗雷德,艾米丽):-

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

?- 兼容(X,Y),兼容(X,Y):-,阅读(X),阅读(Y)兼容(X,Y):-,足球(X),足球(Y)兼容(X,Y):-,朋友(X,Y)。
兼容(X,Y):- 相互(X,Y),。

朋友(X,Y):- havemet(X,Y),兼容(X,Y)。
朋友(约翰,卡尔):-朋友(卡尔,约翰):-havemet(X,Y) :- false,met(X,Y)。
已经满足(X,Y):- 满足(Y,X)。

相互(X,Y):-,朋友(X,Temp),朋友(Y,Temp)相互(X,Y):-,朋友(Temp,X),朋友(Y,Temp)。
相互(X,Y):-朋友(X,Temp),朋友(Temp,Y)相互(X,Y):-,朋友(Temp,X),朋友(Temp,Y)。

遇见(卡尔,艾米丽)。
遇见(弗雷德,詹姆斯): -遇见(弗雷德,艾米丽):-

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

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

于 2013-01-27T20:27:05.810 回答
2

What Prolog system are you using? Are you required to use a particular system?

Your program as it is will not terminate in a standard Prolog, but will in a Prolog with tabling support, such as XSB-Prolog http://xsb.sourceforge.net/ or B-Prolog http://www.probp.com/ - just add :- auto_table. as a first line of your program.

| ?- compatible(john, X).
compatible(john, X).
X = john ?;
X = james ?;
X = carl ?;
X = emily ?;
no
于 2013-01-27T21:18:22.810 回答
2

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

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

于 2013-01-27T14:05:09.340 回答