Около месяца назад один товарищ просил помочь ему решить задачу на Prolog. Я сам по маленьку пролог изучаю, но тогда мне было не до этого. Если вдруг автору всё ещё актуально, предлагаю свой вариант решения - на основе множеств.
Для интересующихся, напоминаю задачу:
Область определения - люди колледжа.
- Все выпускники Итона в колледже играют в крикет.
- Никто, кроме преподавателей, не обедает за верхним столом.
- Ни один из тех, кто играет в крикет, не умеет грести.
- Все мои друзья в этом колледже выпускники Итона.
- Все преподаватели прекрасные гребцы.
Вывод: все мои друзья не преподаватели.
Решение:
set(eton_alumni).
set(lecturers).
set(friends).
set(cricket_players).
set(rowers).
set(dinner).
subset(eton_alumni, cricket_players). % all Eton alumni are cricket players
subset(dinner, lecturers). % nobody except lecturers dinners at upper table
subset(friends, eton_alumni). % all of my friends are Eton alumni
subset(lecturers, rowers). % all lecturers are good rowers
subset(X, X):- set(X).
nsubset(X, Y):- subset(X, Y), !.
nsubset(X, Y):- subset(X, Z), X \= Z, nsubset(Z, Y).
intersection(X, X, _):- !.
intersection(X, Y, _):- nsubset(X, Y), !.
intersection(X, Y, _):- nsubset(Z, X), X \= Z, intersection(Z, Y, 0), !.
intersection(Y, X, 0):- intersection(X, Y, 1).
no_intersection(cricket_players, rowers, _):- !. % no cricket players are rowers
no_intersection(X, Y, _):- nsubset(X, Z), X \= Z, no_intersection(Z, Y, 0), !.
no_intersection(Y, X, 0):- no_intersection(X, Y, 1).
intersection_possible(X, Y):-
intersection(X, Y, 0);
not(no_intersection(X, Y, 0)).
run:- not(intersection_possible(friends, lecturers)).
Если есть какие либо замечания/предложения/комментарии по поводу вариантов решения - с удовольствием выслушаю.