- •1. Вступ в логічне програмування
- •1.1. Виникнення логічного програмування
- •1.2. Сучасний стан логічного програмування
- •Опис задачі на пролозі. Факти і правила
- •2.1. Опис задачі на пролозі
- •2.2. Факти
- •Цільове твердження
- •Умовні твердження
- •Приклад програми на пролозі
- •2.6. Виконання програми на пролозі
- •2.7. Статична та динамічна бази даних
- •2.8. Підготовка фактів для внутрішньої бази даних
- •2.9. Опис фактів внутрішньої бази даних
- •2.10. Предикати роботи з внутрішньою базою даних
- •2.11. Приклади використання внутрішньої бази даних
- •3. Основні поняття visual-prolog
- •3.1. Загальні відомості
- •3.3. Домени елементарних об’єктів
- •3.4. Терми
- •3.4.1. Константа
- •Анонімна змінна
- •3.4.3. Структури
- •3.5. Програма на пролозі
- •4. Механізми прологу
- •Механізм узгодження цілі з базою даних
- •4.2. Механізм звороту
- •4.3. Механізм звороту і відсік
- •4.4. Рекурсія
- •4.4.1. Рекурсивний метод розв’язку задач
- •Рекурсивні методи 2-х доменів:
- •Застосуємо висхідний метод рекурсії до розв’язку задачі:
- •Висхідна рекурсія
- •4.4.4. Предикат repeат
- •Міркування про те, як треба писати програму
- •5. Обробка рядків
- •5.1. Загальні відомості
- •1.1 Стандартні предикати обробки рядків
- •5.3. Лексиграфічне порівняння рядків
- •2Низхідна рекурсія
- •6.1. Метод низхідної рекурсії
- •6.2. Загальна характеристика рекурсивних методів
- •6.3. Низхідна та висхідна рекурсії
- •7. Робота зі списками
- •7.1. Списки. Оголошення списків
- •7.2. Увід-вивід списків
- •7.3. Основна операція на списках
- •7.4. Формування списків стандартним предикатом
- •Процедура з’єднує два списки.
- •Процедура розділяє список на два за вказаним елементом.
- •2.1 Сортування списків на пролозі
- •Сортування методом пухирця
- •7.8. Складені списки
- •8. Предикати вводу-вивіду
- •8.1. Предикати вводу
- •8.2. Предикати виводу
- •9. Файли
- •9.1. Символічне ім’я файлу
- •9.2. Вхідний і вихідний потоки
- •9.3. Організація файлу та методи доступу до файлу
- •9.4. Робота з файлами різними методами доступу
- •9.5. Закриття файлу
- •9.6. Предикати роботи з каталогами
- •9.7. Предикати, що працюють з атрибутами файлів
- •Література
Анонімна змінна
Предикат повинний мати стільки аргументів, скільки описано в секції Predicates. Предикат, що має іншу кількість елементів, вважається іншим предикатом.
Якщо у предикаті використовують декілька аргументів, але не всі вони потрібні в певному твердженні, то для непотрібних аргументів використовують анонімну змінну. Анонімна змінна позначається “_”.
Наприклад: Нехай предикат sved містить відомості про табельний номер робітника і його прізвище. Для процедури, необхідно мати тільки табельний номер. Тоді предикат можна записати sved(Tab, _).
Через анонімну змінну не можна передати значення від твердження до твердження. Анонімна змінна розриває ланцюжок зчеплених змінних. Анонімна змінна заощаджує пам'ять стеку.
3.4.3. Структури
В Пролозі існують стандартні структури і структури користувача. До стандартних структур відносять списки, файли, дерева. Структури: списки, дерева розташовані в оперативній пам’яті. Структури - файли розташовані на зовнішніх носіях. Списки Прологу однодоменні, тобто всі елементи списку одного типу. Структури у яких елементи одного типу називають регулярними.
Приклад списку:
L=['а', 'b', 'с', 'd'] , де базовий елемент списку – тип char.
Структури користувача визначаються за допомогою функтору. Функтор указує на ознаку, за якою збираються об'єкти в структуру.
Наприклад: структура, що задає адресу людини:
Ad = adress („Київ”, „Чарівна”, 25)
(місто, вулиця, будинок)
Вигляд структури схожий на вигляд предикату. Тому треба знати правило, як їх відрізняти.
Структури відрізняють від предикату по місцю опису і по використанню:
структуру описують в Domains, предикат в Predicates;
структуру використовують на місце аргументу предикату, а предикат для утворення тверджень.
3.5. Програма на пролозі
Програма на Пролозі містить предикати, дані і їх описи. Програма поділяється на секції об’яв і секції з твердженнями. Порядок секцій такий, що об’єкти програми, описуються раніше, ніж використовуються.
Секція Constants (константи)
Іменовані константи визначаються в секції Constants ідентифікатором і значенням, що привласнюється ідентифікатору.
Constants
kvartal=4
Т= ”Текст”
Кожна іменована константа записується в новому рядку.
Константа може задаватися виразом:
Constants
kvartal=24
number = 12 / kvartal.
Іменована константа kvartal повинна визначатися раніше запису виразу. Якщо константа задається виразом, то у виразі не можна посилатися на ту ж константу.
У програмі може бути кілька секцій Соnstаnts. Якщо секцій декілька, то вони збираються компілятором в одну.
Ідентифікатор константи глобальний по всій програмі, тому не можна двічі визначати один і той же ідентифікатор.
При запису ідентифікатору констант у секції Constants можна використовувати як великі, так і малі букви. Але при використанні константи у виразі треба записувати ідентифікатор малими буквами, щоб відрізняти константу від змінної.
Секція [Global] Domains (область)
В секції Domains описують структури і типи даних користувача.
Структура визначається у вигляді:
<Ідентифікатор типу структури> =
<функтор>(<тип поля>,...,<тип поля>)
Стандартна структура список визначається:
<Ідентифікатор типу списку> = <тип базового елементу>*
Програміст сам обирає ідентифікатор для типу структури, типу поля, функтору. Опис кожного типу розміщується в окремому рядку секції.
Типи користувача вводяться для забезпечення розуміння програми, а також для опису структур. Тип користувача прив’язують до поля структури, або аргументу предикату.
Тип користувача – визначається через стандартний тип..
Приклад:
Domains
rr, mm, dd = integer
dat = data (rr, mm,dd)
list = integer*
В секції Domains об’явлено типи користувача: тип рік, тип місяць і тип день. Ці типи використовуються при визначенні типу структури dat. З опису структури ясно, що структура записується у вигляді: data (2004, 04,21).
В секції об’явлено також тип списку. Такий список записується: [2,5, 35, 8]. Секція Domains може об’являтися глобальною і бути доступною всім модулям програми.
Секція [Global] Database (база даних)
Використовують для опису фактів, які завантажуються в динамічну базу даних. Синтаксис опису фактів такий же як в секції Predicates. В одному модулю предикат повинен об’являтися один раз, незалежно від секції в якій він об’являється. Секції бувають одна неіменована і декілька іменованих.
Секція [Global] Predicates (предикати)
В секції Predicates описують предикати користувача. Стандартні предикати відомі Турбо – системі, тому їх не описують. Користувач при призначенні ідентифікаторів не повинний використовувати зарезервовані слова.
На твердження з предикатами можна дивитися як на процедури, а на їхні аргументи як на фактичні і формальні параметри. Тому при виборі функторів предикатів їх обирають за дією, що виконує процедура. Разом з предикатами визначають типи їх аргументів. Предикат може не мати аргументів, або мати декілька аргументів. Обмежень на кількість аргументів немає.
Наприклад:
Predicates
find_element /* Предикат не має аргументів */
pas (integer, integer, real) /* Предикат має три аргументи */
Функтор предикату записується за правилами запису ідентифікатору. Функтор може починатися, як з великої букви , так і з малої. Два предикати, що мають однаковий функтор, але відрізняються кількістю і (або) типом аргументів вважаються різними.
Наприклад, предикати вказані нижче різні:
Predicates
Zamena()
Zamena(integer, integer)
Zamena(real, string)
Zamena(integer)
Що стосується доменів аргументів, то вони можуть бути стандартними, структурними типами або типами користувача.
Секція Clauses (твердження)
В секції розміщуються умовні твердження і факти.
Твердження, що утворюються за допомогою одного предикату повинні розміщуватися підряд. Групу тверджень з одним предикатом називають процедурою.
Правила запису тверджень секції вимагають, щоб:
Факти записувалися перед умовними твердженнями, за винятком вимоги процедури до іншого порядку.
При запису умовного твердження умови, що переходять на інший рядок записують під умовами. Умовне твердження треба виділяти. Перехід на інший рядок можливий в будь якому місці.
Розглянемо приклад.
Завдання: Вивести на екран прізвище студента по введеному № групи. Вибирати перше прізвище, що зустрілося.
Predicates
Student(integer, string)
Go(integer)
Goal
Readln(Gr), Go(Gr).
Clauses
Student (“Коваленко”, 410 ).
Student (“Василенко”, 410).
Student (“Петренко”, 420).
Student (“Ткаченко”, 420).
Go(Gr):-student(Fam, Gr),
write(Fam, “ “, Gr), Gr=420.
Go(_).
Група фактів, яка записана за допомогою предикату Student – є процедура. Факти записані на початку секції Clauses.
Умовне твердження, що записано за допомогою предикату Go і факт Do – теж процедура. Але в процедурі факт записано після умовного твердження. Якщо факт розташувати з початку, то ціль Go спів ставиться з фактом Go і прізвище студента не буде одержано.
Секція Goal (ціль)
В секції записується тільки одна ціль. Ціль може записуватися у формі запису тіла правила.
Приклади запису цілі:
Goal
Do.
/* Одиночна ціль */
Goal /*Кон’юнкція цілей: ціль Do(N), write(N). істина, якщо істині обидві поточні цілі */
Goal /*Диз’юнкція цілей: ціль буде істина, якщо буде
істинним один з двох наборів цілей */
Find(Fam), write(Fam); /*перший набір цілей */
Write(“Прізвище не знайдено”). /*другий набір цілей */