2. Методичні вказівки
Цей розділ самодостатній: він містить усю теорію, потрібну для роботи, — поняття предиката як відношення, синтаксис мови Prolog (факти, правила, запити), стислий опис уніфікації та пошуку з поверненням, опис середовища SWISH і техніку вираження родинних відношень через базові предикати — а також повний демонстраційний приклад. Зовнішні джерела не потрібні. Теоретичне підґрунтя — Лекція 6 «Логіка предикатів».
2.1 Предикат як відношення
Нагадаємо з Лекції 6: предикат — це правило, що кожному набору об’єктів зі своєї області визначення ставить у відповідність одне з двох значень з області значень (істина / хиба). Кількість аргументів називають місністю (арністю) предиката:
- одномісний предикат — « є чоловіком»;
- двомісний предикат — « є батьком ».

Кожен предикат рівносильний відношенню — множині тих наборів, на яких він істинний. -місний предикат над задає підмножину декартового степеня:
Так, — це підмножина пар : усі пари , для яких « батько » істинно. Саме цей погляд — предикат як перелік істинних наборів — робить логіку предикатів придатною для програмування: у Prolog ми просто перелічуємо істинні набори (факти) і описуємо правилами, як з одних істинних наборів дістати інші.
Зауваження (базові та похідні предикати). У цій роботі , , , — базові: їхні істинні набори перелічують явно. Решту (, тощо) не перелічують, а обчислюють — задають логічною формулою над базовими. У цьому і полягає ощадність логічного опису: кілька десятків фактів + кілька правил описують сотні істинних наборів похідних відношень.
2.2 Синтаксис Prolog: факти, правила, запити
Prolog (від PROgrammation en LOGique) — мова декларативного програмування: програму складають не як послідовність команд, а як набір тверджень логіки предикатів. Програма — це база знань із трьох видів речень.
Атоми та змінні
Перш ніж писати речення, засвоїмо головне синтаксичне правило Prolog:
| Пишеться | Що це | Приклади |
|---|---|---|
| з малої літери | атом — конкретна стала (ім’я об’єкта чи предиката) | ivan, petro, man, father |
з великої літери або _ |
змінна — «якийсь об’єкт», значення якого добирає інтерпретатор | X, Y, Z, Person, _ |
Типова помилка. Ім’я, записане з великої літери, Prolog вважає змінною, а не константою. Тому реальне ім’я «Іван» не можна записати як
Ivan— це буде змінна. Записуйте константи з малої (ivan) або, якщо потрібні саме кириличні імена з великої літери, беріть їх в одинарні лапки:'Іван'. У цій роботі радимо вживати короткі атоми з малої літери (транслітерацію), як у прикладах нижче.
Окрема анонімна змінна _ означає «будь-що, значення не цікавить»: запит
father(ivan, _) питає «чи є в ivan хоч якась дитина».
Факти
Факт стверджує, що предикат істинний на конкретних сталих. Це найпростіше речення: голова без умов, завершена крапкою.
man(ivan). % «ivan — чоловік» істинно
woman(maria). % «maria — жінка» істинно
father(ivan, petro). % «ivan є батьком petro» істинно
mother(maria, petro). % «maria є матір'ю petro» істинно
Набір фактів — це і є явний перелік істинних наборів базового предиката (його відношення з §2.1).
Правила
Правило визначає предикат через інші предикати. Воно має вигляд
Голова :- Тіло.
і читається «Голова істинна, якщо істинне Тіло». Знак :- — це імплікація
«якщо» (тіло голова), а кома в тілі — кон’юнкція (логічне «і», ):
parent(X, Y) :- father(X, Y). % X — один із батьків Y, якщо X — батько Y,
parent(X, Y) :- mother(X, Y). % або (окреме правило) якщо X — мати Y.
Два правила з однаковою головою — це диз’юнкція («або»): parent істинний, якщо
істинне перше тіло або друге. Змінні в правилі універсально квантовані:
parent(X, Y) :- father(X, Y) означає «для всіх : якщо , то
». А змінна, що трапляється лише в тілі (не в голові),
існує — вона квантована (див. §2.5).
Запити (питання)
Запит — це питання до бази знань; його ставлять після запрошення ?-. Prolog
шукає, чи можна вивести запит із фактів і правил.
?- man(ivan). % true — є такий факт
?- man(maria). % false — такого факту немає й вивести не можна
?- father(ivan, X). % X = petro ; X = oleh ; X = olha — усі діти ivan
Якщо в запиті є змінна, Prolog повертає підстановки, за яких запит істинний. Кілька відповідей перебирають по черзі (див. §2.3).
Зауваження (припущення замкненого світу). Відповідь
falseозначає не «хибно за означенням», а «не вивідно з наявних знань». Prolog вважає хибним усе, чого не можна довести з бази (closed-world assumption). Тому база має містити всі потрібні факти: забули факт — і залежні запити повертатимутьfalse.
2.3 Уніфікація та пошук із поверненням
Виконуючи запит, Prolog зіставляє ціль (goal) з головами речень за допомогою
уніфікації — пошуку такої підстановки значень змінних, за якої два вирази стають
однаковими. Наприклад, ціль father(ivan, X) уніфікується з фактом
father(ivan, petro), зв’язуючи X = petro.
Якщо цілей кілька (тіло правила — кон’юнкція), Prolog доводить їх зліва направо.
Коли якась ціль має кілька способів справдитися, інтерпретатор бере перший, а
решту запам’ятовує; якщо згодом виникає невдача — він вертається (backtracking) до
останньої точки вибору й пробує наступний варіант. У SWISH наступну відповідь просять,
натиснувши ; (крапка з комою) або кнопку Next.
Приклад. За фактами father(ivan, petro), father(ivan, oleh),
father(ivan, olha) запит father(ivan, X) дає послідовно X = petro, потім (після
;) X = oleh, потім X = olha, а далі — false (варіантів більше немає). Саме так
Prolog «обходить» усі істинні набори предиката.
2.4 Середовище SWISH
SWISH — онлайн-версія SWI-Prolog: https://swish.swi-prolog.org/. Реєстрація не потрібна, працює у браузері. Робоче вікно поділене на дві частини:
- Ліва панель — програма. Сюди вводять факти й правила (усю базу знань). Кириличні символи підтримуються (файл у кодуванні UTF-8), але атоми все одно мають починатися з малої літери.
- Права нижня панель — запити. Поле з підказкою
?-. Введіть запит і натисніть Run! (абоCtrl+Enter). Для наступної відповіді натисніть;/ Next, для припинення перебору — Stop.
Порядок роботи: наберіть програму ліворуч → поставте запит праворуч → натисніть
Run! → за потреби перебирайте відповіді через ;. Для звіту зручно робити
знімки екрана (скріншоти) кожного запиту разом з відповіддю. Будь-який інший
інтерпретатор Prolog (наприклад, десктопний SWI-Prolog) теж підійде.
2.5 Родинні відношення через базові предикати
Ключова ідея роботи — виразити складні відношення формулою над базовими. Спочатку введемо зручний допоміжний предикат «бути одним із батьків»:
Мовою Prolog диз’юнкцію зручно подати двома правилами з однаковою головою (див.
§2.2). Далі всі відношення виражають через parent, man, woman та нерівність.
Приклад: предикат «брат»
« — брат » означає: — чоловік, у та є спільний батько або мати, і та — різні особи:
Змінна (спільний предок) квантована : достатньо, щоб знайшовся хоч один спільний із та батько чи мати. У правилі Prolog вона просто трапляється лише в тілі:
brother(X, Y) :-
man(X), % X — чоловік
parent(Z, X), % Z — один із батьків X
parent(Z, Y), % той самий Z — один із батьків Y
X \= Y. % X та Y — різні особи

Типова помилка (пропущена нерівність). Без цілі
X \= Yкожен був би сам собі братом:parent(Z, X)іparent(Z, X)уніфікуються з тим самимZ, тожbrother(petro, petro)хибно вивелося б якtrue. Оператор\=означає «не уніфікуються» (не можуть бути зроблені рівними) — на сталих це звичайне «не дорівнює».
Решта відношень — за тим самим зразком
Аналогічно (наведено логічні означення; коди для власного дерева ви пишете самі — див. 4task.md):
- Сестра. — те саме, але — жінка.
- Батьки. — (батько) і (мати) є батьками спільної дитини .
- Дід / баба (композиція «через покоління»). : — батько когось (), хто є одним із батьків . Для баби беруть замість .
- Дядько / тітка. : — брат одного з батьків . Для тітки — замість .
- Двоюрідні. , де . Тобто батьки і батьки — рідні брат/сестра; звідси спільний дід або баба, але різні батьки.
Зверніть увагу на прийом композиції відношень: «дід» — це «батько» ∘ «батько-чи-мати», «дядько» — «брат» ∘ «батько-чи-мати». Він працює завдяки спільній змінній (), квантованій : вона «склеює» два кроки в ланцюжок.
2.6 Демонстраційний приклад
Нижче — повна невелика база знань (те саме дерево, що на рисунку) з одним похідним
предикатом brother і запитами до нього. Скопіюйте її в ліву панель SWISH і
повторіть запити.

% ---------- Факти: стать -------------------------------------------------
man(ivan). man(petro). man(oleh). man(andrii). man(taras).
woman(maria). woman(nina). woman(halyna). woman(olha). woman(sofia).
% ---------- Факти: батьківство (father(X, Y): X — батько Y) --------------
father(ivan, petro). father(ivan, oleh). father(ivan, olha).
father(petro, andrii). father(petro, sofia).
father(oleh, taras).
% ---------- Факти: материнство (mother(X, Y): X — мати Y) ----------------
mother(maria, petro). mother(maria, oleh). mother(maria, olha).
mother(nina, andrii). mother(nina, sofia).
mother(halyna, taras).
% ---------- Похідні предикати -------------------------------------------
parent(X, Y) :- father(X, Y).
parent(X, Y) :- mother(X, Y).
brother(X, Y) :-
man(X),
parent(Z, X),
parent(Z, Y),
X \= Y.
Запити та очікувані відповіді (у правій панелі; ; — прохання про наступну відповідь):
?- father(ivan, petro).
true.
?- parent(P, andrii).
P = petro ;
P = nina ;
false.
?- brother(petro, olha).
true.
?- brother(taras, _).
false. % у taras немає рідних братів/сестер
?- brother(X, olha).
X = petro ;
X = petro ;
X = oleh ;
X = oleh ;
false.
Зауваження (повтори у відповідях). В останньому запиті
petroтаolehз’являються двічі. Це не помилка:petro— братolhaчерез спільного батькаivanі через спільну матірmaria, тобто існує два різні доведення, і пошук із поверненням показує кожне окремо. Якщо потрібні лише різні імена, у SWI-Prolog це роблять предикатамиdistinct/1абоsetof/3(виходить за межі базового рівня; згадайте про повтори у висновках звіту).
2.7 Типові помилки та поради
- Велика літера в імені.
Petro— це змінна, а не особа. Константи — з малої:petro. - Забутий факт. Через замкнений світ (§2.2) неповна база дає
falseтам, де ви очікуєтеtrue. Спершу переконайтеся, що всіman/woman/father/motherвнесені. - Пропущена нерівність
X \= Y. Дає «сам собі брат/сестра». Додавайте її вbrother,sister, а такожa \= bуcousin. parentлише зfather. Не забудьте друге правило зmother— інакше відношення по материнській лінії «зникнуть».- Плутанина
=та\=.=— уніфікація (спроба зробити рівними),\=— її заперечення. Для порівняння вже відомих сталих цього достатньо. - Крапка в кінці. Кожне речення (факт, правило, запит) завершують крапкою; її брак — найчастіша синтаксична помилка.
- Достатньо велике дерево. Щоб
uncle,aunt,cousinмали відповіді, у вашому дереві мають бути щонайменше двоє дітей в однієї пари, і принаймні в двох із них — власні діти (тоді з’являються двоюрідні). Плануйте дерево заздалегідь.