Секція domains Пролог-програми

 

У секції domains описуються будь-які нестандартні домени, використовувані для аргументів предикатів. Домени в Пролозі є аналогами типів в інших мовах. Основними стандартними доменами Пролога є:

char – символ в одиночних лапках (наприклад, 'а');

integer – ціле від -32768 до 32767 (переводиться в дійсне автоматично, якщо необхідно);

real – дійсне (наприклад, -68.72, бе-94, -791е+21);

string – послідовність символів у подвійних лапках (наприклад, "натисніть ввід");

symbol – або набір латинських букв, цифр і символів підкреслення, у якому перший символ - прописна буква (наприклад, n_fax); або послідовність символів, що містить пробіли або починається з малої літери, укладена в лапки (наприклад, "Список СУБД").

file – символічне ім'я файлу, що починається з прописної букви.

Крім стандартних доменів користувач може використовувати свої. Для цього в області оголошення доменів можна використовувати наступні формати:

а) name = stanDom,

де stanDom – один зі стандартних доменов: int, char, real, string або symbol; name – одне або кілька імен доменів. Наприклад, fio=symbol або year, height=integer;

б) mylist = elementDom*,

де mylist – область, що складається зі списків елементів з області elementDom, що може бути визначена користувачем або мати стандартний тип. Наприклад, number5th = integer* або letter = char*;

в) myCompDom=functor1(d11,...,d1n); functor2(d21,..., d2n); ... functorm(dm1,...,dmq),

де myCompDom – область, що складається зі складених об'єктів, описуваних вказівкою функтора та областей для всіх компонентів. Права частина такого опису може визначати кілька альтернатив, розділених ";" або "or". Кожна альтернатива повинна містити єдиний функтор, і опис типів для компонентів dij. Наприклад,

auto = car(symbol,integer),

packing = box(integer, integer, integer); bottle(integer)

описує дві області auto і packing. Область auto відповідає двокомпонентній структурі з функтором car, а область packing відповідає одній з двох можливих структур box і bottle, що розрізняються не тільки іменами, але і кількістю компонентів.

г) file = name1; name2 ; ... name_n

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

Наприклад, розглянемо побудову структури даних для збереження інформації про комп'ютери. При цьому кожен комп'ютер буде розглядатися як набір вхідних у нього пристроїв, серед яких можуть бути: процесори з указівкою їхнього найменування і частоти, вінчестери із указівкою їхнього обсягу і фірми виготовлювача, також монітори визначеного типу. Область визначення доменів для цього прикладу буде мати вигляд

domains

name , firm , type = symbol

freq , vol = integer

device = processor(name, freq); disk(firm, vol); monitor(type)

computer = device*

У цьому описі домен computer є списком елементів типу device, тобто кожен елемент цього списку може мати структуру типу або processor, або disk, або monitor, що містять одну або два компоненти, кожна з яких має стандартний символьний чи цілий тип.

Секція predicates

 

У секції predicates описуються предикати і типи (домени) аргументів цих предикатів. Імена предикатів повинні починатися з рядкової латинської букви, за якої слідує послідовність букв, цифр і символів підкреслення (до 250 знаків). В іменах предикатів не можна використовувати символи пробілу, мінуса, зірочки, зворотної (і прямій) риски. Оголошення предикатів має форму:

predicates

predicateName_1 (domen_11, domen_12,..., domen_1m)

predicateName_n (domen_n1, domen_n2,..., domen_nk)

де domen_ij – або стандартні домени, або домени, оголошені в секції domains. Оголошення домену аргументу й опис типу аргументу – те саме. Кількість доменів (аргументів) предиката визначають арність (розмірність) предиката. Предикат може не мати аргументів і мати тільки ім'я. Звичайно вибирається таке ім'я предиката, щоб воно відображало визначений вид взаємозв'язку між аргументами предиката. Приклад опису предикатів:

predicates

student( string,real)

start

good_student( string)

Можна використовувати кілька описів того самого предиката. При цьому всі описи повинні слідувати один за іншим і повинні мати однакове число аргументів. Нехай потрібно визначити відношення між трьома аргументами, перші два з яких відповідають доданкам, а третій – сумі двох перших. Цей предикат може бути описаний у наступному виді:

predicates

add(integer,integer,integer)

add(real,real,real)

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

Секція clauses

 

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

Факт – це твердження про існування деякого відношення між аргументами, що позначається ім'ям предиката. Факти – це фрази без умов і вони містять твердження, що завжди абсолютно вірні. Форма запису фактів:

clauses

predicate_Name_1 (term_11, term_12,..., term_1k). ,

...

predicate_Name_N (term_N1, term_N2,..., term_NL).

де predicate_Name_1 – імена предикатів, описаних у секції predicates, a term_11, ..., term_1k – аргументи предикатів (терми), кількість яких повинна відповідати арності опису предиката. Наприклад, факти, що визначають відношення, задане предикатом student, можуть мати вигляд:

clauses

student("Петров" ,4.5).

student("Сидоров" ,3.75).

Правила містять твердження, істинність яких залежить від деяких умов (підцілей), що утворять тіло правила. У Пролозі правила представляються у вигляді

Заголовок :- Підціль_1 , Підціль_2 , ... , Підціль_N. ,

де позначення “:-“ читається як “якщо”, а Заголовок має таку ж форму, як і факт. Тіло правила – це список підцілей, розділених комами. Кому розуміють як кон'юнкцію і читають як “і”. Приклад запису правила

good_student(Name) :- student( Name , В ) ,В > 4.

Для того щоб заголовок правила виявився істинним, необхідно, щоб кожна підціль, що входить у тіло правила, була істинною. Змінні в заголовку правила, квантифіковані універсально. Це означає, що правило, заголовок якого містить змінні, буде істинним для будь-яких термів, що відповідають підцілям правила. З іншої сторони змінні, що входять тільки в тіло правила, квантифіковані екзістенціально. Якщо врахувати таку квантифікацію, то наведене вище правило можна прочитати так:

Для будь-якої особи Name, Name є гарним студентом, ЯКЩО існує середній бал В такий, що Name є студентом із середнім балом В і середній бал В більше 4.

Множина правил, заголовки яких містять однакові імена предикатів і кількість аргументів, називаються процедурою. У Пролозі предикати визначаються (реалізуються) за допомогою процедур. Так наступні два правила

max(Х, Y, X) :- Х >=Y.

max(Х, Y, Y) :- Х < Y.

реалізують процедуру знаходження найбільшого з двох чисел, обумовлену предикатом виду max(number_1, number_2, max_number). Вважається, що між цими двома правилами неявно присутній напевний сполучник “або”.

Секція goal

 

У секції goal задається внутрішня мета програми. Це дозволяє програмі запускатися незалежно від середовища розробки. Якщо внутрішня мета включена в програму, то Пролог виконує пошук тільки одного першого рішення, і зв'язані з змінними значення не виводяться на екран, якщо не передбачити застосування операторів виводу інформації.

У систему Пролог включене більш ніж 200 вбудованих стандартних предикатів і більше дюжини стандартних доменів. У випадку використання цих предикатів і доменів немає необхідності оголошувати їх у програмі.

Розглянемо приклад програми, у якій задана внутрішня мета і використовується звертання до стандартних предикатів:

/* Програма 1.2 */

predicates

hello (string)

goal

hello (_).

clauses

hello (Name):- write("Please, type your name "), readln(Name), nl, write("Welcome ", Name).

У цій програмі запитується Ваше ім'я, а потім воно виводиться на екран.

Перелік і призначення стандартних предикатів наведений у додатку А.

Однак найчастіше метою є складний запит до програми. Для доведення якої-небудь складної мети Пролог повинний довести всі його підцілі, створивши при цьому необхідну множину зв'язаних змінних. Якщо ж одна з підцілей помилкова Пролог повернеться назад і перегляне альтернативні рішення попередніх підцілей, а потім знову піде вперед, але з іншими значеннями змінних. Цей процес називається „пошук з поверненням”.

Секція database

 

Ключове слово database вказує на початок послідовності описів предикатів динамічної бази даних. Динамічна база даних є базою, у яку факти додаються під час виконання програми. Вимоги до описів предикатів такі ж, як і в секції predicates. Факти, що належать динамічній базі даних, обробляються відмінним від звичайних предикатів чином для того, щоб прискорити роботу з БД великого обсягу. Факти динамічної бази можуть модифікуватися протягом сеансу роботи, завантажуватися з дискового файлу за допомогою стандартного предиката consult або записуватися в дисковий файл за допомогою предиката save.