Prolog 查询重复项

Prolog Query Duplicates

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

football(john).
football(sam).

tennis(john).
tennis(pete).

netball(sandy).

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

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

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

提前致谢 - 丹

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

例如,在 SWI-Prolog 中,您可以通过在顶部添加以下指令来执行此操作:

:- table likes/2.

使用此指令,您将获得:

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

如果没有它,您将得到:

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

开桌也称为 SLG 决议

SWI-Prolog 提供库(solution_sequences)

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

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

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

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

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

使用 SICStus Prolog 4.5.0:

| ?- setof(t, likes(pete,X), _).
X = john ? ;
X = sam ? ;
no