4

我已经看到了一些关于这个主题的问题,但是他们都没有真正正确地回答我的问题。我会写一个小例子,这里有一些事实:

football(john).
football(sam).

tennis(john).
tennis(pete).

netball(sandy).

我想创建一个规则,说明pete喜欢任何踢足球或网球的人。

likes(pete, X) :- (football(X) ; tennis(X)), X \= pete.

但很明显,当我在 Prolog 中查询它时,john会出现两次john同时踢足球和网球。我希望它只出现john一次。我怎样才能修改我的代码来做到这一点?

在此先感谢 - 丹

4

3 回答 3

3

一种干净的解决方案是使用 Prolog 系统的表格机制。

例如,在 SWI-Prolog 中,您可以通过在顶部添加以下指令来做到这一点:

:- 表喜欢/2。

使用此指令,您将获得:

?- 喜欢(皮特,X)。
X = 约翰;
X = 山姆。

而没有它,你会得到:

?- 喜欢(皮特,X)。
X = 约翰;
X = 山姆;
X = 约翰。

制表也称为SLG 分辨率

于 2018-08-02T07:49:08.410 回答
2

这是@DanielLyons 在他对您的问题的评论中提到的方法。

它基于,因此可以跨不同的 Prolog 系统移植。

使用 SICStus Prolog 4.5.0:

| ?- setof(t, likes(pete,X), _).
X = john ? ;
X = sam ? ;
no
于 2019-01-29T19:34:15.923 回答
1

SWI-Prolog 提供库(solution_sequences

likes(pete, X) :- distinct( ((football(X) ; tennis(X)), X \= pete) ).

?- likes(pete, X).
X = john ;
X = sam ;
false.

它建立在使表格可用的基础设施之上,非常坚固,因此它对内存存储有类似的要求。

于 2018-08-03T12:18:57.823 回答