Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Логическое программирование1 / 1-3_ЛР_4КСМ_Логічне_прогр._2014-15.doc
Скачиваний:
20
Добавлен:
07.02.2016
Размер:
396.8 Кб
Скачать

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")).