Пролог

Матеріал з Вікіпідручника
Перейти до: навігація, пошук

Вітаємо вас в вікіпідручнику мови пролог. Зауваження, коментарі, і особливо доповнення вітаються.

Вступ[ред.]

Пролог — мова логічного програмування. Пролог заснований на теорії предикатів першого порядку. Назва мови програмування розшифровується як (Програмування в логіці). Ідея використання можливостей наведення теорії предикатів першого порядку — одна з головних переваг мови Пролог для комп'ютерних наук взагалі та штучного інтелекту.

Основними поняттями у мові Пролог є факти, правила логічного висновку та запити, що дозволяють описувати бази знань, процедури логічного виводу та прийняття рішень.

Інсталяція[ред.]

Скачати SWI-Prolog.

Користувачі дебіаноподібних систем можуть зробити ще простіше:

sudo apt-get install swi-prolog

Окрім самого компілятора, нам потрібен також звичайний текстовий редактор. Якщо ви виберете Vim, то допишіть в файл ~/.vimrc наступний текст:

autocmd BufRead *.pro nmap <F6> :!prolog -s %<CR>
autocmd BufRead *.pro set syntax=prolog

Це дозволить нам переходити від редагування файлу, одразу до його виконання та взаємодії з ним, а також увімкне правильну підсвітку синтаксису.

Програми на мові пролог краще зберігати в файлах з розширенням .pro, щоб не плутатись їх мовою Perl, хоча якщо ви на ній не програмуєте, то можете використати і .pl.

Інтерфейс користувача[ред.]

SWI-Prolog запускається командою

swipl

або

prolog

Спочатку, він очікує лише запитів, кожен з яких закінчується крапкою. Спроба написати програму спричинить помилку:

 ?- human(socrates).
ERROR: Undefined procedure: human/1

Тут ?- - привітання системи. Означає що вона очікує запиту.

Програми зберігаються в файлах, і потім передаються інтерпретатору Пролога, за допомогою запиту

?-consult(file). 

який можна написати скорочено:

?-[file].

Щоб ввести програму прямо з клавіатури, потрібно написати команду

?-consult(user).

чи

?-[user].

Тоді все аж до наступного натиснення Ctrl+D дописується в базу даних.

Окрім цього, ви можете запускати пролог одразу з підключеним файлом, написавши:

prolog -s file

, чи якщо в вас налаштований Vim (про що вже було написано вище) - робити це прямо з Vim (кнопкою F6).

Елементи мови[ред.]

Програми мовою Пролог складаються з лексем, які бувають таких видів: предикати, атоми, числа, змінні та структури.

Предикат має вигляд

pred(arg1, arg2, ...  argN).

де, pred - його назва, arg1, arg2, ... argN - аргументи, а в кінці обов'язково ставиться крапка. Також можна описати предикат що не має аргументів (нуль-арний), наприклад:

truth.

Варто також зауважити, що алфавіт в версії SWI-Prolog підтримує надмножину набору 16-розрядних символів Unicode[1], тому в програмах можна використовувати кирилицю:

факультет(кібернетики).

Атоми - це певні константи, імена яких починаються з маленької літери, наприклад

hello
multiWordAtom
x32

Для розділювання слів в атомі можна використати символ підкреслювання (але не мінус і не пропуск):

правильна_назва_атома
неправильна назва
ще-одна-неправильна
1_неправильна_бо_починається_не_з_літери

Крім того, атоми можна брати в одинарні лапки, тоді їх можна називати як завгодно:

'Іван Іванов'
'SWI-Prolog'

Змінна починається з великої літери, або символа підкреслювання:

Variable
_1

Також в файлі можна писати два види коментарів, які ігноруються прологом:

% однорядковий коментар
/*
багаторядковий
коментар
*/

Початок[ред.]

Давайте створимо файл, наприклад hello.pro, і запишемо в нього наприклад такі рядки:

greek(socrates).
greek(plato).
greek(aristotle).

Таку програму часом називають базою даних, чи базою знань. Це звісно деяка неповага до стародавніх філософів писати їх імена з маленької букви, але Пролог чутливий до регістру, і константи записуються саме з маленької букви, тому доведеться потерпіти. Тепер запустимо нашу програму в інтерпретаторі (як це зробити написано в розділі вище), задамо питання:

?- greek(socrates).
true.

Ще одне питання:

?- greek(diogenes).
false.

бачимо що Пролог не має такого поняття як "не знаю", і завжди дає конкретну відповідь.

Можна задати запит:

?- greek(Who).
Who = socrates . 

Who, як і інший довільний ідентифікатор позначає змінну. Варто зауважити, що якщо змінна може мати кілька варіантів, виводиться перший, а далі інерпретатор очікує нашої реації. Якщо ми натиснемо ;, то буде виведено наступний варіант якщо такий є, якщо натиснемо ↵ Enter, то перебір завершиться. Можна отримати всіх греків:

?- greek(X).
X = socrates ;
X = plato ;
X = aristotle.

Щоб завершити інтерактивну сесію введіть

halt.

І не забувайте ставити крапки в кінці тверджень. Або натисніть Ctrl+D.

Предикати та запити[ред.]

Факти в Пролозі задаються за допомогою істинних предикатів. Предикати можуть мати кілька змінних. Наприклад так можна записати факт того, що вчителем Арістотеля був Платон:

mentor(aristotle,plato)

І аналогічно можна записати хто був вчителем Платона:

mentor(plato,socrates).

Тепер, можна запитати хто був вчителем Платона:

?- mentor(plato,X).
X = socrates.

Чи взагалі дати всі можливі пари вчитель - учень:

?- mentor(X,Y).
X = plato,
Y = socrates ;
X = aristotle,
Y = plato.

Можна створити складніший запит:

?- mentor(X,Y),mentor(Y,Z).
X = aristotle,
Y = plato,
Z = socrates.

Тут кома означає кон'юнкцію (логічне "i"), тобто знайти всіх таких X,Y,Z, що Y вчив X, а Z вчив Y.

Анонімна змінна[ред.]

Змінними є всі ідентифікатори що починаються з великої букви. Але окрім звичайних змінних, є змінна що позначається "_", і називається анонімною. Якщо вживати її в запиті, це означатиме, що значення тієї змінної нас не цікавить. Наприклад, щоб перелічити всіх вчителів філософії можна написати:

?- mentor(X,_).
X = plato ;
X = aristotle.

Анонімну змінну можна використати також і в описі даних. Вона означатиме "всі" значення. Наприклад:

human(_).

що для довільного аргументу, навіть якщо такий не згадували в базі значення предикату буде true:

?- human(dog).
true.

Правила[ред.]

Правило в Пролозі виглядає так:

a:- b, c, d.

І означає те, що a буде true, лише коли b, c та d будуть true. Ми можемо створити таку базу даних:

a :- b, c, d.
b.
c.
d :- e.
e.

І коли ми запитаємо a., пролог вияснить, що b і c true, бо так записано, і d true, лише коли e. Але e - теж факт, тому відповідь буде true.

Проте правила цікавіші, коли вони містять предикати зі змінними. Давайте доповнимо наших персонажів учнем Арістотеля - Александром:

greek(socrates).
greek(plato).
greek(aristotle).
macedon(alexander).

mentor(plato,socrates).
mentor(aristotle,plato).
mentor(alexander,aristotle).

Тепер можна написати правило, за яким Греки та Македонці - люди:

human(X):- greek(X);macedon(X).

Крапка з комою означає диз'юнкцію (логічне "або").

?- human(X).
X = socrates ;
X = plato ;
X = aristotle ;
X = alexander.

Можна також придумати правило за яким студентом X є Y, якщо вчителем Y є X.

student(X,Y):- mentor(Y,X).

Рекурсивні правила[ред.]

Порівняння, присвоєння, співставлення[ред.]

is - оператор, який обчислює вираз що знаходиться справа від нього, і намагається співставити те що зліва з тим що справа.

?- 4 is 2+2.
true.
?- X is 2+2.
X = 4.

Вирази зліва не зачіпаються.

?- 2+2 is 4.
false.
?- 2+2 = 4.
false.

?- 2+2 == 4.
false.

?- 4 == 4.
true.

?- 4 == 2+2.
false.

?- 2+2 =:= 2+2.
true.

?- X = 2+2.
X = 2+2.

?- X =:= 2+2.
ERROR: =:=/2: Arguments are not sufficiently instantiated

Посилання[ред.]

  1. Adventure in Prolog
  1. http://www.swi-prolog.org/man/widechars.html