2009-11-22 109 views
1

我有一个由以下规则组成的数据库;序言列表问题

speaks(fred [german, english, dutch]). 
speaks(mary [spanish, arabic, dutch]). 
speaks(jim [norwegian, italian, english]). 
speaks(sam [polish, swedish, danish]). 

作为一个更大的计划的一部分,我怎么会发现3人谁讲同一种语言?

+5

它不应该是'讲(弗雷德,[德,英语,荷兰语])。(注意额外的逗号)? 另外:这功课?如果是这样,请将其标记为家庭作业。 – Franz 2009-11-22 15:34:41

+0

它确实有一点家常气味。 – nedned 2009-11-24 14:21:23

回答

0

它已经有一段时间,所以可能有一些语法毛刺,但我希望你的想法...

% Find out whether an element is contained in a list 
in_list(X,[X|_]). 
in_list(X,[First|Rest]) :- in_list(X,Rest). 

% Find out 3 people who speak the same language 
findspeakers(Language, X1, X2, X3) :- speaks(X1, L1), speaks(X2, L2), speaks(X3, L3), in_list(Language, L1), in_list(Language, L2), in_list(Language, L3). 

很简单使用的解决方案列表操作(我没有记住是否有一个内置的规则来确定一个变量是否包含在列表中,所以我重写了它)。

你可以找到的三个人用下面的命令说英语组:

findspeakers('English', X1, X2, X3). 

你可以找到的三个人全部群体来讲的共同语言使用以下命令:

findspeakers(Language, X1, X2, X3). 

注意:这些命令会给你三人一组的所有可能的组合,所以如果你有四个人说英语,第一个命令会为您提供四个结果集。

+0

我可能会很累,但我认为在这种情况下会得到64个结果集,因为它会生成重复允许的排列,而不是重复禁止的组合。 – bcat 2009-11-22 16:17:10

+0

另外,确实有一个谓词可以完成你的'in_list/2'所做的事情:'member/2'。我认为它不符合ISO标准,但它应该具有近乎全面的支持作为扩展。 – bcat 2009-11-22 16:23:00

+0

啊,很酷。感谢您的评论。特别是第一个非常有趣 - 我不知道...... – Franz 2009-11-22 17:09:31

3

正因为如此,Franz' solution将无法​​正常工作:它将返回讲同一种语言prople的三倍,但这些三元可能包含重复。因此,人们仍然必须诉诸于例如sort/2length/2找到了答案,原来的问题:

?- findspeakers(Language, X1, X2, X3), sort([X1, X2, X3], Y), length(Y, 3). 
false. 

(因此,答案是没有,有没有三个人说同一种语言。)无论如何,我认为一个更优雅的解决方案存在:

spoken(L, S) :- 
    speaks(S, LL), member(L, LL). 

same_language(N, L, SS) :- 
    bagof(S, spoken(L, S), SS), length(SS, N). 

谓词spoken/2使用member/2如果语言L被人S讲成功。 same_language/3成功如果列表SS包含N不同的人,所有这些都讲的语言L。这个谓词使用bagof/3;如果speak/2谓词的定义包含重复数据,则应该使用setof/3代替。

观察,这很好的可以推广的问题:我们现在可以回答任何ñ的问题,而不仅仅是3.示范:

?- same_language(3, L, SS). 
false. 

?- same_language(2, L, SS). 
L = dutch, 
SS = [fred, mary] ; 
L = english, 
SS = [fred, jim] ; 
false. 
+0

哇。很好的答案。你的很多超过我的Prolog知识;) – Franz 2009-11-22 17:22:45

+0

是的,我的也是。我一直想要了解'bagof'和'setof'是如何工作的,这是一个很好的例子。 – bcat 2009-11-22 17:49:04