ТЕСТОВИЙ ПРИКЛАД
Findall(X,Goal,Instances),length(Instances,N).
Size_of(A,(member(A,X),member(A,Y)),N).
Not (bulls_and_cows_match(OldGuess,Guess,B,C)).
% Відповідають бики й корови
bulls_and_cows_match(OldGuess,Guess,B,C):-
exact_matches(OldGuess,Guess,N1),%Точно співпадають
B =:= N1,% Вірне число биків
common_members(OldGuess,Guess,N2), % Спільні члени
C =:= N2 - B.% Вірне число корів
% Оцінка гіпотези
ask(Guess):-repeat, write_ln(['Як багато биків і корів у
',Guess,'?']), nl,
read((Bulls,Cows)), sensible(Bulls,Cows), !,
assert(query(Guess,Bulls,Cows)), Bulls=:=4.
% допустимо
sensible(Bulls,Cows):-
integer(Bulls),integer(Cows),Bulls+Cows=4.
% предикат cleanup звільнює пам'ять від результатів попереднього виконання програми, або попереднього виконання правила "видатний розум" (попередньої гри).
% У даному предикаті використається вбудований предикат retractall(_), який звільняє пам'ять від доданих раніше динамічних фактів ( ця програма на протязі гри зберігає значення кожного "ходу".
cleanup :- retractall(query(_,_,_)).%Чистка (видалити запити)
% Повідомлення
announce :- size_of(X,query(X,A,B),N),
write_ln([' Знайдено відповідь після',N,' queries']).
%кількість точних співпадінь
exact_matches(X,Y,N):- size_of(A,same_place(A,X,Y),N).
%кількість спільних членів
common_members(X,Y,N):-
%Знайти множину запитів
size_of(X,Goal,N) :-
%однакове місце
same_place(X,[X|Xs],[X|Ys]).
same_place(A,[X|Xs],[Y|Ys]):-same_place(A,Xs,Ys).
% довжина списку
length(Xs,N) :- length(Xs,0,N).
length([],N,N).
length([X|Xs],Acc,N) :- Acc1 = Acc + 1, length(Xs,Acc1,N).
Щоб запустити програму потрібно викликати предикат "master_mind (Code)".
Потім програма згенерує перший варіант рішення й запитає, скільки в ньому биків та скільки корів.
!!!!!!!!!!!!!!!!! (не забуваємо ставити крапки після кожного уведення значення) !!!!!!!!!!!!!!!!!
Процедура повторюється, поки програма не "відгадає" і не відобразить вірний варіант
От протокол виконання програми для загаданого числа 4759:
1 ?- master_mind (Code).
Гіпотеза [1, 2, 3, 4]
Скільки биків?
|: 0.
Скільки корів?
|: 1.
Гіпотеза [2, 5, 6, 7]
Скільки биків?
|: 0.
Скільки корів?
|: 2.
Гіпотеза [3, 6, 5, 8]
Скільки биків?
|: 1.
Скільки корів?
|: 0.
Гіпотеза [4, 6, 7, 9]
Скільки биків?
|: 2.
Скільки корів?
|: 1.
Гіпотеза [4, 7, 5, 9]
Скільки биків?
|: 4.
Скільки корів?
|: 0.
Знайдено відповідь після 5 запитів.
Висновки.
· Для розв'язку задач у логічному програмуванні застосовується метод породження й перевірок.
· Насправді будь-який доказ так чи інакше використовує цей метод.
· При цьому проміжні етапи перевірки відтинають подальші гілки від повного дерева перебору, реалізуючи метод гілок і границь.
· Те, наскільки багато гілок відтинається, визначає ефективність розв'язку задач.
· При розв'язку практичних задач важливо
o Вибрати зручне подання стану задачі.
o Побудувати перебір методу гілок і границь, щоб відтинати найбільш об'ємні гілки дерева.
o Іноді неявний перебір і правильний вибір способу подання знань дозволяє розв'язати задачу в чисто декларативному стилі.
Завдання для самостійної роботи
1. Троє хлопців вийшли гуляти із собакою, кішкою й хом'ячком. Відомо, що Петя не любить кішок і живе в одному під'їзді з господаркою хом'ячка. Лена дружить із Танею, що гуляє з кішкою. Визначити, з якою твариною гуляв кожний з дітей?
2. Вітя, Юра й Миша сиділи на скамейці. У якому порядку вони
сиділи, якщо відомо, що:
Юра сидів ліворуч від Миші й праворуч від Віті.
3. П'ять піонерів Алик, Боря, Вітя, Лена й Даша приїхали в табір з 5 різних міст: Харкова, Умані, Полтави, Слов'янська й Краматорська. Є 4 вірних твердження:
1) Якщо Алик не з Умані, то Боря із Краматорська.
2) Або Боря, або Вітя приїхали з Харкова.
3) Якщо Вітя не зі Слов'янська, те Лена приїхала з Харкова.
4) Або Даша приїхала з Умані, або Лена із Краматорська.
Хто звідки приїхав?
4. Чотири чоловіки грають у доміно. Їхні прізвища Кузнєцов, Токарєв, Слесарев і Резчиков. Професія кожного гравця відповідає прізвищу одного з інших гравців. Вірними є три твердження:
Навпроти Кузнєцова сидить слюсар.
Навпроти Резчикова сидить різьбяр.
Праворуч від Слесарева сидить токар.
Хто сидить ліворуч від коваля?
5. В одній школі уроки по історії, математиці, біології, географії, англійській і французькій мові вели три вчителі - Морозов, Васильєв і Токарєв. Кожний з них викладав два предмети.
Географ і вчитель французької мови - сусіди по будинку.
Учитель біології старший за вчителя математики. Морозов - наймолодший.
У понеділок перший урок за розкладом у Токарєва, у біолога й у вчителя французької мови.
У неділю Морозов, математик і вчитель англійської були на риболовлі.
Які предмети викладає кожен учитель?
6. Є чотири боксери: Томас Герберт, Герберт Френсис, Френсис Джеймс і Джеймс Томас.
Герберт набагато сильніше за Томаса.
Френсис сильніший і за Томаса, і за Герберта. Герберт слабший за Джеймса, але сильніший за Френсиса.
У якому порядку потрібно розташувати боксерів від слабшого до найсильнішого?
7. Є чотири кошеня - Дружок, Єлисей, Фантик і Мурлика й чотири хлопчики - Миша, Максим, Льоня й Дмитрик. Кожен хлопчик узяв собі кошеняти улюбленого кольору.
При цьому:
1) Фантик - не рудий & Мурлика - не сірий
2) Дружок - не білий & Єлисей - не сірий
3) У Миші - чорне кошеня & У Максима - Мурлика
4) У Льоні – Єлисей & У Дмитрика - біле кошеня
5) Дмитрик не взяв Фантика & Дружок - не сірий
Одне із цих п'яти тверджень помилкове.
У якого хлопчика яке кошеня?