Вот одна формулировка, предназначенная для решения вашей проблемы. Он немного подробный и не особенно эффективный, но он должен быть достаточно ясным.
all_diff(L) :- \+ (select(X,L,R), memberchk(X,R)).
countries([england,usa,australia]).
country(X) :-
countries(C), member(X, C).
placings([1,2,3]).
placing(X) :-
placings(C), member(X, C).
sports([tennis,cricket,basketball]).
sport(X) :-
sports(C), member(X, C).
names([michael, simon, sigurd]).
name(X) :-
names(C), member(X, C).
solution(Solution) :-
Solution = [E1, E2, E3],
E1 = [michael, C1, S1, P1],
E2 = [simon, C2, S2, P2],
E3 = [sigurd, C3, S3, P3],
country(C1),
country(C2),
country(C3),
all_diff([C1,C2,C3]),
sport(S1),
sport(S2),
sport(S3),
all_diff([S1,S2,S3]),
placing(P1),
placing(P2),
placing(P3),
all_diff([P1,P2,P3]),
member([michael,CMichael,basketball,PMichael], Solution),
CMichael \= usa,
member([_,usa,_,PAmerican], Solution),
PMichael < PAmerican,
member([simon,england,tennis,_], Solution),
member([_,_,cricket,1], Solution).
Однако, как сказал Дэниел Лайонс, нет на самом деле нет решения этого набора ограничений:
?- solution(S).
false.
Если вы стучите окончательное ограничение (то есть один про игрок в крикет с первой место), вы можете увидеть, что будет решения:
?- solution(S).
S = [[michael, australia, basketball, 1], [simon, england, tennis, 2], [sigurd, usa, cricket, 3]] ;
S = [[michael, australia, basketball, 1], [simon, england, tennis, 3], [sigurd, usa, cricket, 2]] ;
S = [[michael, australia, basketball, 2], [simon, england, tennis, 1], [sigurd, usa, cricket, 3]] ;
false.
Если рецептура ЗАГАДКИ были изменены, чтобы этот последний факт:
«Игрок по крикету занял второе место».
... вы бы иметь уникальное решение:
?- solution(S).
S = [[michael, australia, basketball, 1], [simon, england, tennis, 3], [sigurd, usa, cricket, 2]] ;
Как и в сторону: это вполне приемлемо (и иногда предпочтительнее) использовать подход Daniel Львиный для определения, например, набор видов спорта как совокупность отдельных фактов (возможно, более элегантный в этом случае). Тем не менее, мой опыт работы с нетривиальными программами PL обучил меня тому, что обычно удобнее указывать коллекцию в виде списка, с дополнительным предикатом для перечисления отдельных членов этого списка. Это упрощает работу с этими членами по отдельности или в виде полной коллекции.
Пожалуйста, попробуйте что-нибудь, прежде чем оставлять вопрос. Начните с перевода на синтаксис Prolog фактов, данных вам в описании проблемы. Затем напишите запрос на эти факты. – dasblinkenlight