Как бы то ни было, 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
.
Заметим, что это хорошо обобщается проблему: теперь мы можем ответить на вопрос, для любогоп, а не только 3. Демонстрация:
?- same_language(3, L, SS).
false.
?- same_language(2, L, SS).
L = dutch,
SS = [fred, mary] ;
L = english,
SS = [fred, jim] ;
false.
Если не то 'говорит (Фреда, [немецкий , английский, голландский]). '(обратите внимание на дополнительную запятую)? Также: это домашнее задание? Если это так, пожалуйста, пометьте его как домашнюю работу. – Franz
У этого есть немного домашнего труда. – nedned