DOMAINS
журналист=symbol
номер=integer
блюдо=symbol
содержание=symbol
гипотеза=гипотеза(запись,содержание)
запись=запись(журналист,номер)
список_истинности=список_содержаний*
список_содержаний=содержание*
список_журналистов=журналист*
список_списков=список_блюд*
список_блюд=блюдо*
PREDICATES
nondeterm наблюдение(запись,блюдо)
nondeterm один_из(журналист,список_журналистов)
nondeterm один_из(список_содержаний,список_истинности)
nondeterm проверка(гипотеза,список_блюд,список_блюд)
nondeterm является_блюдом(блюдо,список_блюд,список_блюд)
nondeterm не_является_блюдом(блюдо,список_блюд,список_блюд)
nondeterm человек_съел(список_списков)
nondeterm входит_в(блюдо,список_блюд)
CLAUSES
% Правила для формирования гипотезы
один_из(Т,[Т|_]).
один_из(Т,[_|Остаток_списка]):-один_из(Т,Остаток_списка).
% Принадлежность элемента списку
входит_в(X,[X|_]).
входит_в(X,[_|Хвост]):-входит_в(X,Хвост).
% Добавление и удаление элемента из списка
является_блюдом(B,[],[B]).
является_блюдом(B,C,C):-входит_в(B,C),!.
является_блюдом(B,[H|C],[H|C1]):-
является_блюдом(B,C,C1).
не_является_блюдом(_,[],[]).
не_является_блюдом(B,[B|T],T1):-
не_является_блюдом(B,T,T1).
не_является_блюдом(B,[H|T],[H|T1]):-
not(B=H),
не_является_блюдом(B,T,T1).
% Правила для проверки гипотезы
проверка(гипотеза(Запись,истина),Список,Что_съел):-
наблюдение(Запись,Блюдо),
является_блюдом(Блюдо,Список,Что_съел).
проверка(гипотеза(Запись,ложь),Список,Что_съел):-
наблюдение(Запись,Блюдо),
входит_в(Блюдо,Список),
не_является_блюдом(Блюдо,Список,Что_съел).
% Описание высказываний из условий задачи
%Жюль. Сначала он выпил виски, затем съел утку с апельсинами и десерт. Наконец, он выпил кофе.
наблюдение(запись(жюль,1),"виски").
наблюдение(запись(жюль,2),"утка_с_апельсинами").
наблюдение(запись(жюль,3),"десерт").
наблюдение(запись(жюль,4),"кофе").
%Жак. Он выпил аперитив, а затем съел пирог и грушу "прекрасная Елена".
наблюдение(запись(жак,1),"аперитив").
наблюдение(запись(жак,2),"пирог").
наблюдение(запись(жак,3),"груша").
%Джим. Сначала он выпил виски, затем съел пирог и клубничный шербет. А закончил он завтрак чашкой кофе.
наблюдение(запись(джим,1),"виски").
наблюдение(запись(джим,2),"пирог").
наблюдение(запись(джим,3),"клубничный_щербет").
наблюдение(запись(джим,4),"кофе").
% Правила поиска решения
человек_съел(Список_блюд):-
% Формируем базовый список высказываний и гипотез
Первое=[виски,аперитив],
Второе=[утка_с_апельсинами,пирог],
Десерт=[груша,клубничный_щербет,десерт],
Наконец=[кофе],
Список=[жюль,жак,джим],
Список_истинности=[[лжет,прав,прав,прав],
[прав,лжет,прав,прав],
[прав,прав,лжет,прав],
[прав,прав,прав,лжет]],
один_из(С1,Список),
Г11=гипотеза(запись(С1,1),прав),
Г12=гипотеза(запись(С1,2),прав),
Г13=гипотеза(запись(С1,3),прав),
Г14=гипотеза(запись(С1,4),прав),
один_из(С2,Список), not(С1=С2),
Г21=гипотеза(запись(С2,1),лжет),
Г22=гипотеза(запись(С2,2),лжет),
Г23=гипотеза(запись(С2,3),лжет),
Г24=гипотеза(запись(С2,4),лжет),
один_из(С3,Список), not(С1=С3),not(С2=С3),
один_из([И1,И2,И3,И4],Список_истинности),
Г31=гипотеза(запись(С3,1),И1),
Г32=гипотеза(запись(С3,2),И2),
Г33=гипотеза(запись(С3,3),И3),
Г34=гипотеза(запись(С3,4),И4),
проверка(Г11,Первое,Первое),
проверка(Г12,Второе,Второе),
проверка(Г13,Десерт,Десерт),
проверка(Г14,Наконец,Наконец),
проверка(Г21,Первое,Первое),
проверка(Г22,Второе,Второе),
проверка(Г23,Десерт,Десерт),
проверка(Г24,Наконец,Наконец),
проверка(Г31,Первое,Первое),
проверка(Г32,Второе,Второе),
проверка(Г33,Десерт,Десерт),
проверка(Г34,Наконец,Наконец),
Список_блюд=[Первое,Второе,Десерт,Наконец].
GOAL человек_съел([_,_,На_десерт,_]).