开发者

Prolog list question

I have a database consisting of the following rules;

speaks(fred [german, english, dutch]).
speaks(mary [spanish, arabic, dutch]).
speaks(jim [norwegian, italian, e开发者_如何学编程nglish]).
speaks(sam [polish, swedish, danish]).

etc

As part of a much larger program, how would I find out 3 people who speak the same language?

Jen


As it is, Franz' solution will not work: it returns triples of prople which speak the same language, but these triples may contain duplicates. Thus one would still have to resort to e.g. sort/2 and length/2 to find the answer to the original question:

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

(So the answer is no, there are no three people speaking the same language.) Anyway, I think a more elegant solution exists:

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

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

The predicate spoken/2 uses member/2 and succeeds if language L is spoken by person S. same_language/3 succeeds if the list SS contains N distinct people, all of which speak language L. This predicate uses bagof/3; if the definition of the speak/2 predicate contains duplicate data, then you should use setof/3 instead.

Observe that this nicely generalises the problem: we can now answer the question for any n, not just 3. Demonstration:

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

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


It's been a while, so there might be some syntax glitches, but I hope you get the idea...

% 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).

Pretty simple solution using list operators (I didn't remember whether there was a built-in rule for finding out whether a variable is contained in a list, so I rewrote it).

You can find out groups of three people speaking English with the following command:

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

You can find all groups of three people speaking a common language with the following command:

findspeakers(Language, X1, X2, X3).

NOTE: These commands will give you all possible combinations of groups of three people, so if you have four people speaking English, the first command will give you four result sets.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜