
- •Лабораторна робота 1
- •1 План виконання лабораторної роботи
- •2 Основні теоретичні відомості
- •2 Контрольні питання
- •4 Індивідуальні контрольні завдання
- •Лабораторна робота 2
- •2.2. Інструментальне середовище розробника мови Пролог
- •2.2.1. Особливості реалізацій мови Пролог
- •2.2.2. Типові програми для опановування інструментального середовища розробника мови Пролог
- •4. Контрольні питання
- •5. Контрольні завдання
- •5.1. Загальні контрольні завдання
- •5.2. Індивідуальні контрольні завдання
- •Лабораторна робота 3
- •1 План виконання лабораторної роботи
- •2 Основні теоретичні відомості
- •2.1. Основи логічного програмування мовою Пролог
- •2.2. Використання правил у запитах до Пролог-програм
- •2.3. Розміщення предикату not у конструкціях правил Пролог-програм
- •2.4. Робота зі складеними об'єктами у Пролог-програмах
- •2.5. Методичні рекомендації до опрацьовування контрольних питань і виконання контрольних завдань лабораторної роботи
- •3. Контрольні питання
- •4. Завдання для самоперевірки
- •5. Контрольні завдання
- •5.1. Контрольне завдання 1
- •5.2. Контрольне завдання 2
- •6. Література
- •Вимоги до оформлення, захисту та оцінювання лабораторних робіт
- •Зразок оформлення титульного аркуша звіту про виконання лабораторної роботи
2.3. Розміщення предикату not у конструкціях правил Пролог-програм
Логічне заперечення деякого предикату задаєтся за допомогою вбудованого предикату not.
При програмуванні на Пролозі, використання заперечення буває зручним для логічного виведення нових фактів із уже наявних в базі даних фактів.
У цілому, використання предикату not у конструкції правила часто дає можливість ввести до програми додаткові елементи логіки.
Наприклад, можна використати питання з запереченням для визначення того, чи є сусідами дві вибрані країни.
Замість того, щоб видавати на екран список усіх пар країн із загальним кордоном, а потім візуально шукати всі ті пари країн, які не потрапили до списку, можна скористатися простішим та ефективнішим засобом – запереченням (not).
Так, предикат not(border(Country1,Country2)) видає всі пари країн, які не межують одна з одною.
Припустимо, ви хочете знати, чи не межують між собою Германія та Іспанія.
Запит формулюється наступним чином:
not (border("Germany", "Spain")).
Програма "Пари країн Європи" (лістинг 4) є завершеною програмою на Пролозі для розв`язування поставленої вище задачі.
/* Лістинг 4 */
/* Програма "Пари країн Європи" */
domains
country = symbol
predicates
euro_pair(country,country)
border(country,country)
find_non_border_pair
goal
find_non_border_pair.
clauses
/* факти */
euro_pair("France","Germany").
euro_pair("France","Spain").
euro_pair("France","Italy").
euro_pair("Germany","Spain").
euro_pair("Germany","Italy").
euro_pair("Spain","Italy").
border("France","Germany").
border("France","Spain").
border("France","Italy").
/* правила */
find_non_border_pair :-
euro_pair(X,Y),
not(border(X,Y)),
write(X," - ",Y),nl.
/***** кінець програми *****/
2.4. Робота зі складеними об'єктами у Пролог-програмах
Об`єкти тверджень являють собою дані, що можуть мати як просту, так і складну структуру.
Тип простих об`єктів і структур обмежений шістьма вбудованими типами доменів Прологу.
Складеними структурами називають такі предикати, що були скомпоновані зі складених об`єктів.
При цьому під складеним об`єктом розуміють такий об`єкт, який представляє деякий інший об`єкт або певну сукупність об`єктів.
Ті прості об`єкти, що представляють складені об'єкти, поміщають у дужки.
Наприклад, можна ввести складений об`єкт fruits, який робить більш наочним опис відносини likes: likes("Tom",fruits(apples,orange,banana)).
Перший терм складеного об`єту називється функтором та є предикатом, хоча він і розташований усередині іншого предикату.
У наведеному вище прикладі, функтором є fruits.
Для полегшення написання тверджень і предикатів у формі складених об`єктів і структур, Пролог надає можливість оголошувати складені об`єкти в розділі domains.
Якщо структура містить об`єкти різних типів, то вона називається багатодоменною структурою.
Складений об`єкт є певною структурою доменів, де кожна підструктура передбачає особливе подання фактів у базі даних і забезпечує конкретний засіб сортування об`єктів за категоріями.
Посилання на доменну структуру здійснюються за іменем функтору.
Програма "Бібліотека" (лістинг 5) демонструє використання доменної структури з ім`ям personal_library, що містить відомості про книжки з особистих колекцій.
Функтор структури personal_library має ім`я book.
Предикат, що використовує структуру personal_library, визначається наступним чином:
collection(collector,personal_library)
Опис предикату collection містить два імені об`єктів:
– ім`я collector відноситься до звичайного об`єкту;
– ім`я personal_library відноситься до структури з декількох об`єктів.
Програма «Бібліотека» використовує зовнішню ціль, яка полягає в знаходженні всіх книг колекціонера Сміта.
Для того, щоб дізнатися, які книги належать Сміту, необхідно ввести цільове твердження, в якому об`єкт smith є окремим значенням із домену collector, а Books – вільною змінною:
collection(smith,Books).
Припустимо, що ви також бажаєте знати імена власників і назви книг, надрукованих у 1967 році.
Ціль для пошуку вказаної інформації буде містити дві вільні змінні (Сollector і Title) та дві анонімні змінні (підкреслювання «_» буде означати, що вас не цікавлять об`єкти з родовими іменами author і publisher, тобто кожне таке підкреслювання буде заміняти анонімну змінну):
collection(Collector,book(Title,_,_,1967)).
Відзначимо, що застосування доменної структури значно спрощує розуміння та практичне використання структури предикату.
У підсумку, застосування структур суттєво підвищує зручність користування створеною базою даних.
При цьому, чим більше було введено функторів, тим більш визначені запити можна адресувати до бази даних, а саме такі запити являють собою найбільший інтерес.
/* Лістинг 5. Програма “Бібліотека” */
domains
personal_library = book(title, author, publisher, year)
/* персональна бібліотека = книга(назва,автор,видавництво,рік видання) */
collector,title,author,publisher = symbol
year = integer
predicates
collection(collector, personal_library)
/* колекція (ім`я колекціонеру, бібліотека) */
clauses
collection(kahn,
book("The Computer and the Brain", "von Neumann","Yale University Press",1958)).
collection(kahn,
book("Symbolic Logic", "Lewis Carroll", "Dower Publications",1958)).
collection(johnson,
book("Database: A Primer", "C.J.Date", "Addison-Wesley",1983)).
collection(johnson,
book("Problem-Solving Methods in AI", "Nils Nilsson", "McGraw Hill",1971)).
collection(smith,
book("Alice in Wonderland", "Lewis Carroll", "The New American Library",1960)).
collection(smith,
book("Fables of Aesop", "Aesop-Calder", "Dover Publications",1967)).
/***** кінець програми *****/
Подання даних часто вимагає наявності великої кількості структур, які в Пролозі повинні бути описані в розділі domains.
Більше того, виникають труднощі з тими предикатами, що працюють із об`єктами цих доменів.
Для усування даного недоліку, Пролог пропонує користувачу альтернативні описи доменів.
Програма "Предмети" (лістинг 6) демонструє наочний приклад застосування альтернативних описів доменів.
У програмі "Предмети" використовуються три доменних структури:
1) misc_thing, із одним об`єктом whatever;
2) book, із двома об`єктами – author и title;
3) record, із трьома об`єктами – artist, album і type.
Об`єкти всіх трьох структур належать до одного типу symbol та об`єднані під єдиним ім`ям thing.
Альтернативний опис домену thing має наступний вигляд:
thing = misc_thing(whatever);
book(author,title);
record(artist,album,type)
Для розділу альтернативних доменів, застосовується символ «крапка з комою» («;»).
Для пов`язування персони з тим, чим вона володіє, введено простий предикат owns(person,things).
Використання альтернативних доменів дозволяє записувати в твердженнях один предикат owns у застосуванні до різних класів речей.
У разі відсутності зазначеної конструкції, вимагалося би ввести декілька предикатів замість одного, а саме – три предикати.
/* Лістинг 6. ПРОГРАМА “ПРЕДМЕТИ” */
domains
thing = misc_thing(whatever); book(author, title); record(artist, album, type)
person, whatever, author, title, artist, album, type = symbol
predicates
owns(person, thing)
clauses /* ФАКТИ */
/* різноманітні речі */
owns("Bill", misc_thing("sail boat")).
owns("Bill", misc_thing("sports car")).
owns("Jack", misc_thing("Motor cycle")).
owns("Jack", misc_thing("house trailer")).
owns("Beth", misc_thing("Chevy wagon")).
owns("Beth", misc_thing("Piano")).
owns("Linda", misc_thing("motor boat")).
/* книги */
owns("Bill", book("J.R.R. Tolkein", "Return of the Ring")).
owns("Bill", book("James A. Mishener", "Space")).
owns("Jack", book("Manuel Puig", "Kiss of the Spider Woman")).
owns("Beth", book("Frank Herbert", "Dune")).
owns("Beth", book("Tom Clancy", "The Hunt for Red October")).
owns("Linda", book("Garrison Keillor", "Lake Wobegon Days")).
/* грампластинки */
owns("Bill", record("Elton John", "Ice Fair", "popular")).
owns("Bill", record("Michael Jackson – Lionel Richie", "We are the World", "popular")).
owns("Jack", record("Bruce Springsteen", "Born to Run", "popular")).
owns("Jack", record("Benny Goodman", "The King of Swing", "jazz")).
owns("Beth", record("Madonna", "Madonna", "popular")).
Зверніться до програми "Предмети" з цільовим реченням
owns(P, misc_thing(T)).
Переклад цього запиту на природну мову виглядає так: "Перелічіть усі можливі речі, якими хто-небудь володіє".
Спробуйте також запити наступного виду:
owns(_,book(A,T)) и owns(P,record(_,A,_)).
Терми misc_thing, book і record є іменами структур, але в складі предикатних виразів вони одночасно відіграють і роль імен функторів.
Пролог не робить різниці між функтором і доменною структурою.
Даний засіб введено до Прологу спеціально, оскільки він є дуже зручним саме в декларативних мовах.
Наведений нижче програмний фрагмент показує, як виглядала би програма «Предмети» без конструкцій альтернативних описів доменів.
domains
person,whatever,author,title = symbol
artist,album,type = symbol
misc_thing = misc_thing(whatever)
book_library = book(author,title)
record_library = record(artist,album,type)
predicates
personal_thing(person,misc_thing)
personal_books(person,book_library)
personal_records(person,record_library)
clauses
personal_thing("Bill",misc_thing("sail boat")).
personal_books("Bill",book("J.R.R. Tolkein", "Return of the Ring")).
personal_records("Bill",record("Elton John", "Ice of Fire","popular")).