Prolog列表问题

时间:2009-11-22 15:31:34

标签: list prolog

我有一个由以下规则组成的数据库;

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

作为一个更大的计划的一部分,我如何找到3个说同一种语言的人?

2 个答案:

答案 0 :(得分:3)

实际上,Franz' solution将不起作用:它会返回使用相同语言的三元组,但这些三元组可能包含重复项。因此人们仍然不得不诉诸于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代替。

观察这很好地概括了问题:我们现在可以回答任何 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).

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