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.