我已经看到了有关此主题的一些问题,但是这些问题都没有真正回答我的问题。我会写一个小例子,这里有一些事实:
football(john).
football(sam).
tennis(john).
tennis(pete).
netball(sandy).
我想创建一个规则,规定pete
喜欢踢足球或网球的人。
likes(pete, X) :- (football(X) ; tennis(X)), X \= pete.
但是很明显,当我在Prolog中对其进行查询时,john
会同时出现两次,因为john
同时踢足球和网球。我希望它只提出一次john
。我该如何修改我的代码?
预先感谢-丹
答案 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-setof,因此可以在不同的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],
},
//...
]
},
//...
]
}
]
}
它建立在使制表变得困难的基础架构上,因此对内存存储也有类似的要求。