Уніфікація складових об’єктів
На цьому кроці ми розглянемоскладові об'єкти даних та функтори.
Мал.1. Деревоподібна структура дати
Ви можете зробити це, оголосивши домен, що містить складовий об'єктdate:
Такий запис виглядає як фактПрологу, але це не так - це об'єкт даних, який ви можете обробляти поряд із символами та числами. Він починається з імені, званогофунктором(в даному випадкуdate), за яким йдуть три аргументи.
Зверніть увагу, що функтор вПролозі- не те саме, що функція та інших мовах програмування; це просто ім'я, яке визначає вид складеного об'єкта даних та об'єднує разом його аргументи.
Зауваження.Функтор не означає, що будуть виконані будь-які обчислення.
Аргументи складового об'єкта даних можуть бути складовими об'єктами. Наприклад, ви можете розглядати чийсь день народження (рис. 2) як інформацію з наступною структурою:
Мал.2. Деревоподібна структура дати народження
На мовіПрологце виглядає так:
У складового об'єктаbirthdayу цьому прикладі є дві частини: об'єктperson ("Leo","Jensen")та об'єктdate("Apr",14,1900). Функторами цих об'єктів будутьpersonіdate.
Уніфікація складових об'єктів
Складовий об'єкт може бути уніфікований із простою змінною або зі складовим об'єктом (можливо, що містить змінні як частини у внутрішній структурі), який йому відповідає. Це означає, що складовий об'єкт можна використовувати для того, щоб передавати цілий набір значень як єдиний об'єкт, а потім застосовувати уніфікацію для їхнього поділу. Наприклад:
Використання знакарівності для уніфікації складових об'єктів
Прологздійснює уніфікацію у двох випадках. По-перше, коли мета зіставляється із заголовком речень. По-друге, через знак рівності (=), який єінфіксним предикатом(предикатом, розташованим між своїми аргументами, а чи не перед ними).
Використання кількох значень як єдиного цілого
Складові об'єкти можуть розглядатися в пропозиціяхПрологуяк єдині об'єкти, що спрощує написання програм. Розглянемо, наприклад, факт:
John owns a horse named blacky.(У Джона є кінь Блеки.)
Складовими об'єктами у цих двох прикладах є:
то не можна було б визначити, чи єblackyназвою книги чи ім'ям коня. З іншого боку, можна використовувати перший компонент складового об'єкта – функтор для розпізнавання різних об'єктів. Цей приклад використовує функториbookтаhorseдля вказівки різниці між об'єктами.
Зауваження.Складові об'єкти складаються з функтора та об'єктів, що належать цьому функтору, наприклад:functor(objectl,object2. objectN ).
Приклад використання складових об'єктів
Зверніть увагу, що у фактіphone_listшість аргументів, п'ять із них можуть бути розбиті (рис. 3) на два складові об'єкти.
Мал.3. Розбиття складових об'єктів
Може виявитися кориснішим представляти факти те щоб вони відбивали ці складові об'єкти даних. Повернувшись крок назад, бачимо, щоperson(особа) - це ставлення, а ім'я та прізвище - об'єкти. Також,birthday(день народження) - це відношення між трьома аргументами: місяцем, днем та роком. У поданніПрологувони можуть бутизаписані наступним чином:
У цю програму введено два визначення складових доменів. Ми розглянемо деякі подробиці цих складових структур даних далі, а зараз зупинимося назастосуваннітаких складових об'єктів.
Предикатphone_listтепер містить три аргументи, що відрізняється від шести попереднього прикладу. Іноді розбиття даних та складовий об'єкт робить більш ясною логіку програми і може допомогти в обробці даних. А тепер додамо кілька правил до нашої маленької програми. Допустимо, ви хочете створити список людей, у яких день народження цього місяця. Нижче наведено програмуpro35_2.pro, яка вирішує це завдання, використовуючи вбудований предикатdateдля отримання дати із внутрішнього календаря комп'ютера. Предикатdateповертає поточні рік, місяць та день із календаря комп'ютера.
Текст програми можна взяти тут.
Результат роботи програми можна переглянути на рис.4
Мал.4. Результат роботи програмиpro35_2.pro
Завантажте та запустіть цю програму.
-
Програма використовує вікно для виведення результату.
Поміщає у вікні заголовок, який допомагає зрозуміти результат.
Використовує у предикатіget_month__birthdaysвбудований предикатdate.
Крім того, програма здійснює пошук у базі даних і друкує список людей, які народилися цього місяця. Спочатку шукається перша людина у базі даних. Викликphone_list (Person,_,Date)поміщає ім'я та прізвище людини в зміннуPerson, поміщаючи функторpersonцілком уPerson, а день народження - у зміннуDate.
Зауважимо, що потрібні дві змінні: одна для зберігання повного імені людини, а інша - для зберігання дня народження. Цедосягається з допомогою використання складових об'єктів.
Ваша програма тепер може передавати день народження людини просто шляхом передачі змінноїDate. Це відбувається в наступній підцілі, де програма передає поточний місяць (представлений цілим числом) і день народження предикатcheck_birthday_month.
Прологвикликає предикатcheck_birthday_monthз двома змінними: перша змінна пов'язана з цілим, а друга - з термомbirthday. У заголовку правила, яке визначаєcheck_birthday_month,This_month, порівнюється зі змінноюMon. Другий аргумент,Date, зіставляється зb_date(Month,_,_).
Оскільки нас цікавить місяць народження людини, використовуються анонімні змінні для дати та року народження.
Предикатcheck_birtday_monthспочатку перетворює символ місяця на ціле число. Після того, як це зроблено,Прологможе порівняти значення поточного місяця з місяцем народження людини. Якщо це порівняння вдало, підцільcheck_birthday_monthзавершується успішно і обробка продовжується. Якщо порівняння неуспішне (людина народилася в іншому місяці),Прологвідкочується для пошуку іншого рішення задачі.
Наступна підціль, яку потрібно обробити -write_person. Особа, дані якої потрібно обробити, має день народження цього місяця, і тому до звіту потрапляють лише правильні дані. Після друку інформації припущення терпить неуспіх, що викликає пошук із поверненням.