Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекція_4_21_лог_зад.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
420 Кб
Скачать
☆

4. Поліцейська проблема

Jean був убитий у вівторок. Luc, Paul, Alain, Bernard і Louis перебувають під підозрою. Хто є вбивця, якщо прийнято вважати, що:

  • убивцею є той, хто бажав смерті Jean-a, має зброю й не має алібі на вівторок;

  • алібі, представлене персоною, що не викликає довіри, не є дійсним;

  • хтось міг прагнути смерті Jean-a, якщо він був зацікавлений у його смерті або бажав йому помститись;

  • персона може бути зацікавлена в смерті Jean-a, якщо вона успадковує його власність, якщо винна йому грошей або була помічена на місці злочину.

Анкета дала наступні результати:

  • В Luc-a є алібі на вівторок, яке надав Bernard;

  • В Paul-a є алібі на вівторок, яке надав Bernard;

  • В Louis-a є алібі на вівторок, яке надав Luc;

  • В Alain-a є алібі на четвер, яке надав Luc;

  • Alain персона, що не вселяє довіри;

  • Paul прагнув помститись Jean-у;

  • Luc прагнув помститись Jean-у;

  • Bernard є спадкоємцем Jean-a;

  • Jean є спадкоємцем Louis-a;

  • Louis винен грошей Jean-у;

  • Luc винен грошей Jean-у;

  • Paul бачив Alain-a за скоєнням злочину;

  • В Luc-а є зброя;

  • В Louis-а є зброя;

  • В Alain-а є зброя.

Хто вбивця?

ЛІстинг програми (i):

predicates

person(symbol, symbol).

person(symbol,symbol,symbol).

j_s(symbol).

z_s(symbol).

alibi(symbol).

killer(symbol).

goal

killer(X),

write("KILLER -",X), nl.

clauses

person(alain, prest). % Paul бачив Alain-a за скоєнням

злочину

person(louis,money). % Louis винен грошей Jean-у

person(luc,money). % Luc винен грошей Jean-у

person(paul, mesti). % Paul хотів помститись Jean-у

person(luc, mesti). % Luc хотів помститись Jean-у

person(luc, w). % У Luc-а є зброя

person(alain, w). % У Alain-а є зброя

person(louis, w). % У Louis-а є зброя

person(alain, non). % Alain не вселяє довіри

person(luc,tuesday,bernard). % У Luc-a є алібі на

вівторок, яке надав Bernard

person(paul,tuesday,bernard). % У Paul-a є алібі на

вівторок, яке надав Bernard

person(louis,tuesday,luc). % У Louis-a є алібі на

вівторок, яке надав Luc

person(alain,thursday,luc). % У Alain-a є алібі на

четверг, яке надав Luc

person(jean, hear, louis). % Jean є спадкоємцем Louis-a

person(bernard, hear, jean). % Bernard є

спадкоємцем Jean-a

% Вбивцею Jean-а є його спадкоємець, боржник, той,

% кого бачили на місті злочину, або хотів помститись,

%та одночасно мав зброю і не мав алібі.

killer(X) :- j_s(X), person(X,w), not(alibi(X)).

alibi(X) :- person(X,tuesday,_), person(_,tuesday,X);

not(person(X,non)).

j_s(X):- z_s(X); person(X, mesti).

z_s(X):- person(X, hear, jean).

z_s(X):- person(X,money); person(X, prest).

РЕЗУЛЬТАТ:

KILLER – alain

ЛІстинг програмИ (ii):

domains

name, day = symbol

predicates

person(name).

alibi(name,day,name).

persona_non(name).

mesti(name).

heir(name,name).

money(name).

jean_see(name).

weapon(name).

motive(name).

n_al(name).

killer(name).

goal

killer(X),

write("KILLER -",X), nl.

clauses

person(jean).

person(luc).

person(paul).

person(alain).

person(bernard).

person(louis).

alibi(luc,tuesday,bernard). % У Luc-a є алібі на

вівторок, яке надав Bernard alibi(paul,tuesday,bernard). % У Paul-a є алібі на

вівторок, яке надав Bernard

alibi(louis,tuesday,luc). % У Louis-a є алібі на

вівторок, яке надав Luc

alibi(alain,thursday,luc). % У Alain-a є алібі на

четверг, яке надав Luc

persona_non(alain). % Alain не вселяє довіри

mesti(paul). % Paul хотів помститись Jean-у mesti(luc). % Luc хотів помститись Jean-у

heir(bernard,jean). % Bernard є спадкоємцем Jean-a

heir(jean,louis). % Jean є спадкоємцем Louis-a

paul_see(alain). % Paul бачив Alain-a за скоєнням злочину

money(louis). % Louis винен грошей Jean-у

money(luc). % Luc винен грошей Jean-у

weapon(luc). % У Luc-а є зброя

weapon(louis). % У Louis-а є зброя

weapon(alain). % У Alain-а є зброя

% кілер – той, у кого є мотив (щодо помсти, спадку, %боргу) або свідок злочину, та має зброю і нема алібі

n_al(X) :- not(alibi(X,tuesday,_));

not(alibi(_,tuesday,X));

persona_non(X).

motive(X) :- mesti(X); heir(X,_); jean_see(X); money(X).

killer(X) :- motive(X), weapon(X), n_al(X).

Результат:

KILLER - alain

5. Пасажири – книголюби % Якось в одному купе опинились відомі історик, поет, прозаїк і драматург. % Це були Олексіїв, Борисов, Константинів і Дмитриїв. % Сталось, що кожен з них узяв с собою книгу, написану одним з пасажирів. % Олексіїв і Борисов, кожен дочитав свою книгу, умовились на завтра обмінятись ними. % Поет читав п’єсу. % Прозаїк, дуже молода людина, що видрукував свою першу книгу, казав, що він в житті не читав і не читає нічого з історії. % Борисов купив твір Дмитриєва. % Ніхто з пасажирів не купляв і не читав книгу, написану ним. Що читав кожен з них? Хто ким був? CONSTANTS tab = " " % константа для отступів при виводі результатів Domains жанрКниги, жанрПисателя = symbol фамилияПисателя = symbol возможныеФамилии = фамилияПисателя* пассажир = книголюб(фамилияПисателя,

жанрПисателя,списокКниг) списокПассажиров = пассажир* списокСписковПассажиров = списокПассажиров* книга = книга(фамилияПисателя,жанрКниги) списокКниг = книга* predicates nondeterm возможнаяФамилия(фамилияПисателя) nondeterm пишетВЖанре(жанрПисателя,жанрКниги) nondeterm списокПассажировИКниг(списокПассажиров,

списокКниг) nondeterm одинИз(списокПассажиров,списокСписковПассажиров) nondeterm одинИз(пассажир,списокПассажиров) nondeterm одинИз(книга,списокКниг) nondeterm читал(пассажир,книга) nondeterm взялССобой(пассажир,книга) nondeterm ищемРешение(списокПассажиров) % формування унікального списку рішень і форматний вивід у

вікно програми nondeterm уникальные_решения(списокСписковПассажи-

ров,списокСписковПассажиров,

списокСписковПассажиров) nondeterm списокРешений(списокСписковПассажиров) nondeterm выводРешений() nondeterm выводРешений(списокСписковПассажиров) nondeterm печатьРешенияКтоЧтоЧитал(списокПассажиров) nondeterm печатьРешенияКтоКемБыл(списокПассажиров) CLAUSES одинИз(Х,[Первый|Хвост]):- Х=Первый; одинИз(Х,Хвост). % Якось в одному купе опинились відомі історик, поет, прозаїк

і драматург. пишетВЖанре(историк,история). пишетВЖанре(поэт,стихи). пишетВЖанре(прозаик,проза). пишетВЖанре(драматург,пьеса).

% Це були Олексіїв, Борисов, Константинов і Дмитриїв. возможнаяФамилия(алексеев). возможнаяФамилия(борисов). возможнаяФамилия(конст). возможнаяФамилия(дмитриев). списокПассажировИКниг(Пассажиры,Книги):-

% генерує різні унікальні жанри пишетВЖанре(ЖанрПисателя1,_),

пишетВЖанре(ЖанрПисателя2,_),

пишетВЖанре(ЖанрПисателя3,_),

пишетВЖанре(ЖанрПисателя4,_), % унікальність жанрів not(ЖанрПисателя1=ЖанрПисателя2), not(ЖанрПисателя1=ЖанрПисателя3),

not(ЖанрПисателя2=ЖанрПисателя3), not(ЖанрПисателя1=ЖанрПисателя4),

not(ЖанрПисателя2=ЖанрПисателя4),

not(ЖанрПисателя3=ЖанрПисателя4), % список пасажирів, з різними комбінаціями жанрів Алексеев=книголюб(алексеев, ЖанрПисателя1,[_,_]), Борисов = книголюб(борисов, ЖанрПисателя2 ,[_,_]), Константинов = книголюб(конст,ЖанрПисателя3,[_]), Дмитриев = книголюб(дмитриев, ЖанрПисателя4 ,[_]), % впорядкований список пасажирів Пассажиры=[Алексеев,Борисов,Константинов,Дмитриев], % відповідність жанрів пишетВЖанре(ЖанрПисателя1,ЖанрКниги1), пишетВЖанре(ЖанрПисателя2,ЖанрКниги2), пишетВЖанре(ЖанрПисателя3,ЖанрКниги3), пишетВЖанре(ЖанрПисателя4,ЖанрКниги4), % жанр письменника має відповідати жанру

написаної ним книги К1 = книга(алексеев, ЖанрКниги1), К2 = книга(борисов, ЖанрКниги2), К3 = книга(константинов,ЖанрКниги3), К4 = книга(дмитриев, ЖанрКниги4), % впорядкований список книг Книги = [К1,К2,К3,К4]. % співставляє Книгу з однією з ПрочитанихКниг Пасажира читал(Пассажир,Книга):- Пассажир=книголюб(_,_,ПрочитанныеКниги), одинИз(Книга,ПрочитанныеКниги). взялССобой(Пассажир,Книга):- Пассажир = книголюб(_,_,[Книга|_]), читал(Пассажир,Книга). ищемРешение(Пассажиры):- % Гіпотеза % формуються впорядковані списки, де у пасажирів вказані прізвище і жанр (список прочитаних книг невизначений [_]

або [_,_]) % окремо формується список книг, написаних цими

письменниками списокПассажировИКниг(Пассажиры,Книги), одинИз(Алексеев,Пассажиры), одинИз(Борисов,Пассажиры), одинИз(Константинов,Пассажиры), одинИз(Дмитриев,Пассажиры), Поэт = книголюб(_,поэт,_),

одинИз(Поэт,Пассажиры),

Прозаик = книголюб(_,прозаик,_),

одинИз(Прозаик,Пассажиры), % Сталось, що кожен з них узяв с собою книгу, написану одним з пасажирів. % Перевірка на унікальність книг необхідна тут, оскільки % саме тут говоримо, що кожен пасажир читав одну з книг, %написаних іншими пасажирами одинИз(К1,Книги), одинИз(К2,Книги),not(К1=К2), одинИз(К3,Книги),not(К1=К3),not(К2=К3), одинИз(К4,Книги),not(К1=К4),not(К2=К4),not(К3=К4), Пьеса = книга(_,пьеса), одинИз(Пьеса,Книги), КнигаПоИстории = книга(_,история),

одинИз(КнигаПоИстории,Книги), ПроизведениеДмитриева = книга(дмитриев,_),

одинИз(ПроизведениеДмитриева,Книги), НаписалАлексеев = книга(алексеев,_),

одинИз(НаписалАлексеев,Книги), НаписалБорисов = книга(борисов,_),

одинИз(НаписалБорисов,Книги), НаписалКонстантинов = книга(константинов,_),

одинИз(НаписалКонстантинов,Книги),

НаписалДмитриев = книга(дмитриев,_),

одинИз(НаписалДмитриев,Книги),

% у пасажирів заповнюється список книг, таким чином

формуються всі можливі комбінації рішень. % список пасажирів впорядкований. читал(Алексеев,К1),читал(Борисов,К2),

читал(Константинов,К3),читал(Дмитриев,К4), % ПЕРЕВІРКА ГІПОТЕЗИ % % Олексіїв і Борисов, кожен дочитав свою книгу, умовились на завтра обмінятись ними.

Алексеев = книголюб(алексеев,_,

[КнигаЧиталАлексеев,КнигаЧиталБорисов]), Борисов = книголюб(борисов,_,

[КнигаЧиталБорисов,КнигаЧиталАлексеев]), % Поет читав п’єсу. (В смислі: поет узяв з собою п’єсу, тобто % це була його перша прочитана книга і, можливо, єдина).

% поет узяв з собою п’єсу взялССобой(Поэт,Пьеса), % Прозаїк, дуже молода людина, що видрукував свою першу %книгу, казав, що в житті не читав і не читає нічого з історії. not( читал( Прозаик, КнигаПоИстории)), % Борисов купив твір Дмитриєва. взялССобой(Борисов,ПроизведениеДмитриева), % Дмитриев - не прозаїк, т.к. прозаїк випустив всього одну книгу, а Борисов купив одне з декількох творів Дмириева одинИз(Дмитриев,Пассажиры),

Дмитриев = книголюб(дмитриев,НеПрозаик,_), not(НеПрозаик = "прозаик"), % Ніхто з пасажирів не купляв і не читав книгу,

написану ним самим.

not( читал( Алексеев, НаписалАлексеев)), not( читал( Борисов, НаписалБорисов)), not( читал( Константинов, НаписалКонстантинов)), not( читал( Дмитриев, НаписалДмитриев)). % процедура для фільтрації не унікальних рішень уникальные_решения([],Уникальные_Решения,

Уникальные_Решения). уникальные_решения([Решение|Хвост_Решений],

Уникальные_Решения,Уникальные_Решения_Выход):- not(одинИз(Решение,Уникальные_Решения)), уникальные_решения(Хвост_Решений,

[Решение|Уникальные_Решения],

Уникальные_Решения_Выход). уникальные_решения([Решение|Хвост_Решений],

Уникальные_Решения,Уникальные_Решения_Выход):- одинИз(Решение,Уникальные_Решения), уникальные_решения(Хвост_Решений,

Уникальные_Решения,Уникальные_Решения_Выход). % формує список унікальних рішень списокРешений(Список_Уникальных_Решений):- findall(Пассажиры,ищемРешение(Пассажиры),

Список_Всех_Решений), уникальные_решения(Список_Всех_Решений,[],

Список_Уникальных_Решений). % процедура перебирає список рішень і викликає процедуру вивода кожного рішення на екран в читабельному вигляді выводРешений():- списокРешений(Список_Уникальных_Решений), выводРешений(Список_Уникальных_Решений). выводРешений([]). выводРешений([Решение|ОстальныеРешения]):- nl,write("Вывод решения:"),nl, write(tab,"Кто кем был?"),nl, печатьРешенияКтоКемБыл(Решение), write(tab,"Кто что читал?"),nl, печатьРешенияКтоЧтоЧитал(Решение), выводРешений(ОстальныеРешения). % вивід кожного рішення на екран в читабельному вигляді % відповідь на питання: "Кто кем был?" печатьРешенияКтоКемБыл([]). печатьРешенияКтоКемБыл(Пассажиры):- Пассажиры = [Первый|Остальные], Первый = книголюб(Фамилия,Жанр,_), write(tab,tab,Фамилия, " был ", Жанр,"ом"),nl, печатьРешенияКтоКемБыл(Остальные).

% відповідь на питання: "Кто что читал?" печатьРешенияКтоЧтоЧитал([]). печатьРешенияКтоЧтоЧитал(Пассажиры):- Пассажиры = [Первый|Остальные], Первый = книголюб(Фамилия,_,СписокКниг), write(tab,tab,Фамилия, " читал ", СписокКниг),nl, печатьРешенияКтоЧтоЧитал(Остальные). goal % ВІДПОВІДІ НА ПИТАННЯ % выводРешений().

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]