Prolog查询重复项

时间:2018-08-02 02:58:54

标签: prolog prolog-setof prolog-tabling

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

football(john).
football(sam).

tennis(john).
tennis(pete).

netball(sandy).

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

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

但是很明显,当我在Prolog中对其进行查询时,john会同时出现两次,因为john同时踢足球和网球。我希望它只提出一次john。我该如何修改我的代码?

预先感谢-丹

3 个答案:

答案 0 :(得分:3)

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

例如,在SWI-Prolog中,您可以通过在顶部添加以下指令来实现此目的:

:- table likes/2.

使用此指令,您将得到:

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

如果没有它,您将得到:

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

Tabling也称为 SLG分辨率

答案 1 :(得分:2)

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

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

使用SICStus Prolog 4.5.0:

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

答案 2 :(得分:1)

SWI-Prolog提供商品库(solution_sequences

state = {
  foo : [
    bar : {
      users : [
        {
          name : '',
          adddr : '',
          needs : ['a', 'b', 'c'],
          baz : [
            {
              k1 : v1,
              k2 : v2,
              k3 : [1,2,3,4,5],
            },
            //...
          ]
        },
        //...
      ]
    }
  ]
}

它建立在使制表变得困难的基础架构上,因此对内存存储也有类似的要求。