我有一个由以下规则组成的数据库;
speaks(fred [german, english, dutch]).
speaks(mary [spanish, arabic, dutch]).
speaks(jim [norwegian, italian, english]).
speaks(sam [polish, swedish, danish]).
等
作为一个更大的计划的一部分,我如何找到3个说同一种语言的人?
仁
答案 0 :(得分:3)
实际上,Franz' solution将不起作用:它会返回使用相同语言的三元组,但这些三元组可能包含重复项。因此人们仍然不得不诉诸于sort/2
和length/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
代替。
观察这很好地概括了问题:我们现在可以回答任何 n 的问题,而不仅仅是3.演示:
?- same_language(3, L, SS).
false.
?- same_language(2, L, SS).
L = dutch,
SS = [fred, mary] ;
L = english,
SS = [fred, jim] ;
false.
答案 1 :(得分: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).
注意:这些命令将为您提供三人组的所有可能组合,因此如果您有四个人说英语,第一个命令将为您提供四个结果集。