DOMAINS
островетянин, селение=symbol
номер=integer
список_селений=селение*
житель=житель(островетянин, селение)
список_жителей=житель*
ответы=integer*
PREDICATES
nondeterm входит_в(селение, список_селений)
nondeterm входит_в(житель, список_жителей)
nondeterm ответ(номер, житель, список_жителей)
nondeterm проверка(номер, житель, список_жителей,integer)
nondeterm решение(список_жителей)
nondeterm правильные_ответы(селение,ответы)
CLAUSES
входит_в(Голова, [Голова|_]).
входит_в(Голова, [_|Хвост]) :- входит_в(Голова, Хвост).
% (1) X: я живу в том же селении, что и Y.
ответ(1, житель(x, Селение_Х), Живут_в) :-
входит_в(житель(x, Селение_Х), Живут_в), входит_в(житель(y, Селение_Y), Живут_в), Селение_Х=Селение_Y.
% (2) Y: я живу в том же селении, что и Z.
ответ(2, житель(y, Селение_Y), Живут_в) :-
входит_в(житель(y, Селение_Y), Живут_в), входит_в(житель(z, Селение_Z), Живут_в), Селение_Y=Селение_Z.
% (3) Z: ни X, ни Y мне не "земляки".
ответ(3, житель(z, Селение_Z), Живут_в) :-
входит_в(житель(z, Селение_Z), Живут_в), входит_в(житель(x, Селение_Х), Живут_в),
входит_в(житель(y, Селение_Y), Живут_в), not(Селение_Z=Селение_Y), not(Селение_Z=Селение_Х).
% (4) X: Z из Середины-на-Половине.
ответ(4, житель(x, Селение_Х), Живут_в) :-
входит_в(житель(x, Селение_Х), Живут_в), входит_в(житель(z, Селение_Z), Живут_в),
Селение_Z="Середина_на_половине".
% (5) Y: от селения, где живет X, до моего селения такое же расстояние, как от Середины-иа-Половине до Кривдина
ответ(5, житель(y, Селение_Y), Живут_в) :-
входит_в(житель(y, Селение_Y), Живут_в), входит_в(житель(x, Селение_Х), Живут_в), not(Селение_Х=Селение_Y).
% (6) Z: X и Y не из одного селения.
ответ(6, житель(z, Селение_Z), Живут_в) :-
входит_в(житель(z, Селение_Z), Живут_в), входит_в(житель(x, Селение_Х), Живут_в),
входит_в(житель(y, Селение_Y), Живут_в), not(Селение_Х=Селение_Y).
% (7) X: пока мы здесь беседовали, Z успел один раз солгать.
ответ(7, житель(x, Селение_Х), Живут_в) :-
not(ответ(3, житель(z, _), Живут_в)), ответ(6, житель(z, _), Живут_в);
not(ответ(6, житель(z, _), Живут_в)), ответ(3, житель(z, _), Живут_в).
% (8) Y: зато Х все время изрекал только истину.
ответ(8, житель(y, _), Живут_в) :-
ответ(1, житель(x, Селение_Х), Живут_в),
ответ(4, житель(x, Селение_Х), Живут_в),
ответ(7, житель(x, Селение_Х), Живут_в).
% (9) Z: последнее утверждение как у X, так и у Y ложно.
ответ(9, житель(z, _), Живут_в) :-
not(ответ(7, житель(x, _), Живут_в)),
not(ответ(8, житель(y, _), Живут_в)).
проверка(Номер_ответа, Житель, Живут_в,1) :-
ответ(Номер_ответа, Житель, Живут_в).
проверка(Номер_ответа, Житель, Живут_в,0) :-
not(ответ(Номер_ответа, Житель, Живут_в)).
правильные_ответы("Правдычино",[1,1,1]).
правильные_ответы("Кривдино",[0,0,0]).
правильные_ответы("Середина_на_половине",[1,0,1]).
правильные_ответы("Середина_на_половине",[0,1,0]).
решение(Живут_в) :-
Живут_в=[житель(x, Селение_Х), житель(y, Селение_Y), житель(z, Селение_Z)],
Селения=["Правдычино", "Кривдино", "Середина_на_половине"],
входит_в(Селение_Х, Селения), входит_в(Селение_Y, Селения), входит_в(Селение_Z, Селения),
правильные_ответы(Селение_Х,[ОтветX1,ОтветX2,ОтветX3]),
правильные_ответы(Селение_Y,[ОтветY1,ОтветY2,ОтветY3]),
правильные_ответы(Селение_Z,[ОтветZ1,ОтветZ2,ОтветZ3]),
% ПРОВЕРКА: Село_Х не равно Село_Y, Село_Z не равно Село_Y, Село_Х не равно Село_Z
проверка(1, житель(x, Селение_Х), Жители,ОтветX1),
проверка(2, житель(y, Селение_Y), Жители,ОтветY1),
проверка(3, житель(z, Селение_Z), Жители,ОтветZ1),
проверка(4, житель(x, Селение_Х), Жители,ОтветX2),
проверка(5, житель(y, Селение_Y), Жители,ОтветY2),
проверка(6, житель(z, Селение_Z), Жители,ОтветZ2),
проверка(7, житель(x, Селение_Х), Жители,ОтветX3),
проверка(8, житель(y, Селение_Y), Жители,ОтветY3),
проверка(9, житель(z, Селение_Z), Жители,ОтветZ3).
GOAL
решение(Живут_в).