Необходимо внести коррективы в код учебной задачи на Prolog

Узнай цену своей работы

Формулировка задачи:

Помогите пожалуйста внести коррективы 1) Отсутствует структура гипотезы 2) Выводиться должен только 1 уникальный ответ, на данный момент это не так 3) Не все условия работают верно, необходимо провести проверку

Решение задачи: «Необходимо внести коррективы в код учебной задачи на Prolog»

textual
Листинг программы
/*
ТРУДНЫЙ ОБЕД
 
Николай (Н) хотел пригласить на обед по возможности больше соседей:
Алексея (А), Владимира (В), Сергея (С),
Дениса (Д), Егора (Е), Федора (Ф),
Георгия (Г), Харитона (Х).
 
При этом он столкнулся со следующими трудностями:
1. А никогда не придет, если пригласить В или С или если одновременно пригласить Д и Е.
2. Д придет только в том случае, если будет приглашен и Е.
3. Е не примет приглашения, если придет В.
4. Ф наносит визиты только в сопровождении Г.
5. Х не будет возражать против присутствия Ф только в том случае, если будет приглашен и А.
6. Если не будет приглашен Ф, то Х будет против приглашения Е.
7. Чтобы пришел Г, необходимо пригласить Д или Х.
8. Г откажется от приглашения, если пригласят Е без А, а также в случае приглашения В или С.
 
Какое максимальное число гостей и кого именно мог пригласить Н?
*/
 
DOMAINS
целое_число = integer
сосед = н;а;в;с;д;е;ф;г;х
список = сосед*
гипотеза = гипотеза(список, целое_число)
решения = гипотеза*
PREDICATES
nondeterm возможный_сосед(сосед)
nondeterm генерация_гипотезы(гипотеза)
nondeterm длина(список, целое_число, целое_число)
nondeterm между_нулем_и(целое_число, целое_число)
nondeterm входит_в_список(сосед, список)
nondeterm входит_в(сосед, гипотеза)
nondeterm генерация_сочетания(список, целое_число, список)
nondeterm проверка_гипотезы(гипотеза)
nondeterm проверка_правила(целое_число, гипотеза)
nondeterm не_входит_в(сосед, гипотеза)
nondeterm входят_в(список, гипотеза) % входят сразу несколько из соседей
nondeterm поиск_решения(гипотеза)
nondeterm поиск_максимального_решения(гипотеза)
nondeterm максимум(решения, гипотеза, гипотеза)
nondeterm больше(гипотеза, гипотеза)
CLAUSES
%возможный_сосед(н).
возможный_сосед(а).
возможный_сосед(в).
возможный_сосед(с).
возможный_сосед(д).
возможный_сосед(е).
возможный_сосед(ф).
возможный_сосед(г).
возможный_сосед(х).
 
входит_в_список(Элемент, [Элемент|_ОстальныеЭлементы]).
входит_в_список(Элемент, [_ПервыйЭлемент|ОстальныеЭлементы]):-
    входит_в_список(Элемент, ОстальныеЭлементы).
 
входит_в(Элемент, гипотеза(Список, _)) :-
    входит_в_список(Элемент, Список).
    
не_входит_в(Элемент, Гипотеза):-
    NOT(входит_в(Элемент, Гипотеза)).
 
входят_в([], _Гипотеза).
входят_в([Первый|Остальные], Гипотеза):-
    входит_в(Первый, Гипотеза),
    входят_в(Остальные, Гипотеза).
 
длина([], Длина, Длина).
длина([_Первый|Остальные], Буфер, Длина):-
    НовыйБуфер = Буфер + 1,
    длина(Остальные, НовыйБуфер, Длина).
 
между_нулем_и(До, До).
между_нулем_и(До, Число):-
    До > 0,
    МеньшеДо = До - 1,
    между_нулем_и(МеньшеДо, Число).
 
генерация_сочетания(_Список, 0, []).
генерация_сочетания([ПервыйЭлемент|Остальные],
        ДлинаСочетания,
        [ПервыйЭлемент|Подсписок]):-
    ДлинаПодсписка = ДлинаСочетания - 1,
    генерация_сочетания(Остальные, ДлинаПодсписка, Подсписок).
    генерация_сочетания([_ПервыйЭлемент|Остальные], Длина, Подсписок):-
    генерация_сочетания(Остальные, Длина, Подсписок).
 
генерация_гипотезы(гипотеза(Список, КоличествоГостей)):-
    % возьмем всех соседей:
    findall(Сосед, возможный_сосед(Сосед), Соседи),
    % определим их количество:
    длина(Соседи, 0, КоличествоСоседей),
    между_нулем_и(КоличествоСоседей, КоличествоГостей),
    генерация_сочетания(Соседи, КоличествоГостей, Список).
 
проверка_гипотезы(Гипотеза):-
проверка_правила(1, Гипотеза),
проверка_правила(2, Гипотеза),
проверка_правила(3, Гипотеза),
проверка_правила(4, Гипотеза),
проверка_правила(5, Гипотеза),
проверка_правила(6, Гипотеза),
проверка_правила(7, Гипотеза),
проверка_правила(8, Гипотеза).
 
проверка_правила(1, Гипотеза):-
% А никогда не придет, если пригласить В или С или если одновременно пригласить Д и Е.
входит_в(а, Гипотеза), не_входит_в(в, Гипотеза), не_входит_в(с, Гипотеза),
NOT(входят_в([д, е], Гипотеза));
не_входит_в(а, Гипотеза).
 
проверка_правила(2, Гипотеза):-
% Д придет только в том случае, если будет приглашен и Е.
входит_в(д, Гипотеза), входит_в(е, Гипотеза);
не_входит_в(д, Гипотеза).
 
проверка_правила(3, Гипотеза):-
% Е не примет приглашения, если придет В.
входит_в(е, Гипотеза), не_входит_в(в, Гипотеза);
не_входит_в(е, Гипотеза).
 
проверка_правила(4, Гипотеза):-
% Ф наносит визиты только в сопровождении Г.
входит_в(ф, Гипотеза), входит_в(г, Гипотеза);
не_входит_в(ф, Гипотеза).
 
проверка_правила(5, Гипотеза):-
% Х не будет возражать против присутствия Ф только в том случае, если будет приглашен и А.
входит_в(х, Гипотеза), входит_в(ф, Гипотеза), входит_в(а, Гипотеза);
входит_в(х, Гипотеза), не_входит_в(ф, Гипотеза);
не_входит_в(х, Гипотеза).
 
проверка_правила(6, Гипотеза):-
% Если не будет приглашен Ф, то Х будет против приглашения Е.
не_входит_в(ф, Гипотеза), входит_в(х, Гипотеза), не_входит_в(е, Гипотеза);
входит_в(ф, Гипотеза), входит_в(х, Гипотеза);
не_входит_в(х, Гипотеза).
 
проверка_правила(7, Гипотеза):-
% Чтобы пришел Г, необходимо пригласить Д или Х.
входит_в(г, Гипотеза), входит_в(д, Гипотеза);
входит_в(г, Гипотеза), входит_в(х, Гипотеза);
не_входит_в(г, Гипотеза).
 
проверка_правила(8, Гипотеза):-
% Г откажется от приглашения, если пригласят Е без А, а также в случае приглашения В или С.
входит_в(г, Гипотеза), не_входит_в(в, Гипотеза), не_входит_в(с, Гипотеза), входит_в(е, Гипотеза), входит_в(а, Гипотеза);
входит_в(г, Гипотеза), не_входит_в(в, Гипотеза), не_входит_в(с, Гипотеза), не_входит_в(е, Гипотеза);
не_входит_в(г, Гипотеза).
 
поиск_решения(Решение):-
    генерация_гипотезы(Решение),
    проверка_гипотезы(Решение).
 
поиск_максимального_решения(Максимум):-
    findall(Решение, поиск_решения(Решение), Решения),
    Решения = [Первое|Остальные],
    максимум(Остальные, Первое, Максимум).
 
максимум([], Буфер, Буфер).
максимум([Первое|Остальные], Буфер, Максимум):-
    больше(Первое, Буфер), 
    максимум(Остальные, Первое, Максимум).
максимум([Первое|Остальные], Буфер, Максимум):-
    NOT(больше(Первое, Буфер)), 
    максимум(Остальные, Буфер, Максимум).
 
больше(гипотеза(_, Первая), гипотеза(_, Вторая)) :-
    Первая > Вторая.
 
GOAL
поиск_максимального_решения(Решение).

Оцени полезность:

6   голосов , оценка 4.167 из 5