- •2.1 Мета роботи 23
- •3.1 Мета роботи 29
- •4.1 Мета роботи 39
- •Література 51
- •Передмова
- •1 Лабораторна робота № 1 елементарні програми на пролозі. Робота з твердженнями програми за допомогою механізму звороту
- •1.1 Мета роботи
- •1.2 Методичні вказівки до виконання лабораторної роботи
- •1.3 Завдання на лабораторну роботу
- •Дан набір фактів, які мають такі відомості про книги: прізвище автора, назву книги і рік видання. Знайти і вивести на екран по кожному автору назви його книг і їх кількість.
- •1.5 Контрольні питання
- •2 Лабораторна робота № 2 робота з рядками методом висхідної рекурсії
- •2.1 Мета роботи
- •2.2 Методичні вказівки до виконання лабораторної роботи
- •2.3 Завдання на лабораторну роботу
- •2.5 Контрольні запитання
- •3 Лабораторна робота № 3 робота зі списками методом низхідної рекурсії
- •3.1 Мета роботи
- •3.2 Методичні вказівки до виконання лабораторної роботи
- •3.3 Завдання на лабораторну роботу
- •3.5 Контрольні запитання
- •3.5.2 Яким типом даного може бути голова списку і яким типом може бути хвіст списку?
- •4 Лабораторна робота № 4 предикати вводу-виводу.Робота з файлами
- •4.1 Мета роботи
- •4.2 Методичні вказівки до виконання лабораторної роботи
- •4.3 Завдання на лабораторну роботу
- •4.5 Контрольні запитання
- •Додаток а підготовка та виконання програми в середовищі visual prolog 5.2
- •1. Утворення нового проекту в середовищі Visual Prolog 5.2
- •На вкладці General ввести:
- •На вкладці Target обрати:
- •2.Опції компілятору
- •8. Обробка помилок
- •9. Текстовий редактор Visual Prolog
- •Література
2.5 Контрольні запитання
2.5.1 Що таке рекурсія? Чому вона така важлива у Пролозі?
2.5.2 Які методи рекурсії вам відомі? Яку роль відіграють у рекурсії граничні умови? Що буде, якщо значення аргументів рекурсивного виклику не буде сходитись до значень аргументів граничної умови?
2.5.3 Який метод рекурсії вивчили ви? Опишіть роботу цього методу.
2.5.4 Як висхідна рекурсія використовує стек і механізм зчеплення?
2.5.5 Чи передається через анонімну змінну у рекурсивному виклику значення?
2.5.6 Які ви знаєте стандартні предикати роботи з рядками, з якими типами даних вони працюють?
2.5.7 Вказати режими роботи стандартних предикатів роботи з рядками.
3 Лабораторна робота № 3 робота зі списками методом низхідної рекурсії
3.1 Мета роботи
Мета роботи:
навчитися використовувати при програмуванні основну операцію на списках та стандартні процедури обробки списків;
навчитися писати та налагоджувати програми, які оброблюють списки за допомогою низхідної рекурсії.
3.2 Методичні вказівки до виконання лабораторної роботи
3.2.1 Виконайте приклади, що подані нижче. Переконайтесь, що ви розумієте як працює низхідна рекурсія на списках. Виконайте стандартні процедури обробки списків.
Задавайте ціль для стандартної процедури Append різними способами і перевіряйте, як це впливає на роботу процедури Append.
Приклад 1
Ввести список цілих чисел. Порівняти перший і третій елементи списків. Якщо перший елемент більше, то залишити ці елементи на місцях. Інакше поміняти їх місцями.
Domains
List=integer*
Predicates
nondeterm Do(list, list)
Goal
Readterm(list,L),do(L, L1),!.
Clauses
Do([H1,H2,H3| T],L1):- H1>H3,L1= [H1,H2,H3| T],!;
L1=[H3,H2,H1|T].
Do(L,L1):-write("Кількість елементів списку <3",L),nl,L1=[].
Предикат Readterm вводить список з клавіатури, привласнює його змінній L і передає список в предикат do.
Введемо для прикладу список [12, 35, 41, 6, 2].
При зіставленні предикату do з цілі з умовним твердженням виконуються таке зіставлення:
[12, 35, 41, 6, 2] = [H1,H2,H3| T].
Змінні одержують такі значення: H1=12, H2=35, H3= 41, T=[6,2].
При вірній умові H1>H3 вільній змінній L1 привласнюється список [12, 35, 41, 6, 2]. При не вірній умові вільній змінній L1 привласнюється список [41, 35, 12, 6, 2].
Зверніть увагу, що порядок елементів нового списку задається порядком голів списку. А операція „|” працює залежно від конкретизації змінних на приєднання елементу чи на відокремлювання перших елементів списку.
Приклад 2
Ввести з клавіатури відсортований за зростанням числовий список і окреме число. Вставити в список число так, щоб новий список також був відсортований.
Domains
List = real*
Predicates
nondeterm in (list ,list, real)
Goal
write("Введіть спиок за зростанням "),nl,
Readterm(list, L), write("Введіть число "),
readreal(El),in (L, New_List,El),!.
Clauses
In([],[El],El):-!.
In([H1,H2| T], [H1,El,H2| T], El):- H1< El, El<H2,!.
In([H|T],[El, H|T],El):-El<H,!.
In([H|T],[H, El|T],El):-T=[],!.
In([H|T], New_List, El):-!,in(T, T1,El),
New_List = [H|T1].
Програма написана низхідним методом рекурсії.
Програма має 4 граничних умови. Для певного списку і елементу працює тільки одна умова:
перша умова вставляє в порожній список елемент;
друга умова вставляє елемент між двома елементами списку;
третя умова вставляє елемент перед першим елементом списку;
четверта умова вставляє елемент в кінець списку.
Рекурсивна умова відокремлює елемент списку і викликає процедуру з хвостом списку.
Конкретизовані змінні зберігаються в стеку автоматично. Тому елемент списку зберігається в стеку.
Дія повторюється до тих пір, поки не спрацює одна з граничних умов.
Після чого до хвосту списку додається в початок елемент списку зі стеку. Дії повторюються до тих пір, поки стек не спорожніє.
Рекурсивна умова може записуватись також в такому вигляді:
In([H|T], [H|T1], El):-!,in(T, T1,El).
Стандартні процедури обробки списків
Стандартні процедури відомі з літератури, проте їх треба самому вказувати в програмі.
Процедура belongs – перевіряє, чи належить елемент списку.
Domains
list=char*
Predicates
belongs(char, list)
Goal
belongs (‘с’, ['а','b','с'] ). /* Чи належить символ 'с' списку
['а','b','с'] */
Clauses
belongs ( X, [ X | _ ] ):-!. (1)
belongs ( X, [ _ | T] ):– !,belongs ( X, T ). (2)
Якщо голова списку співпадає з вказаним елементом, то працює факт 1, інакше працює правило 2, елемент шукається у хвості списку.
Процедура append – працює у трьох режимах.
Режим роботи процедури залежить від цілі:
Ціль: append ( [ 1, 2 ],[ 3, 4 ], L ). Режим: з'єднання двох списків.
Результат: список L=[ 1, 2, 3, 4 ];
Ціль: append ( Do, [ 2 | Pisly], [ 1, 2, 3] ).Режим: розподіл списку на два списки за даною ознакою.
Результат: Do=[ 1 ], Pisly =[ 3 ];
Ціль: append ( L1, L2, [ 1, 2, 3 ]). Режим: розподіл списку на два списки (усі можливі варіанти). Візуальний Пролог сам перебирає всі розв’язки.
Результати: L1=[ ], L2=[ 1, 2, 3 ];
L1=[ 1 ], L2=[ 2, 3 ];
L1=[ 1, 2 ], L2=[ 3 ];
L1=[ 1, 2, 3 ], L2=[ ].
Процедура Append
Розглянемо другий режим роботи процедури append. Задамо ціль таким чином, щоб елементи списку [1,2,3,4], що стоять перед числом 3 віднести до списку L1, а елементи після числа 3 віднести до списку Т(випадок b).
Domains
list=integer*
Predicates
append(list, list, list)
Clauses
append ( [ ], L, L ).
append ( [F| L1 ], L2, [F | L4 ] ):-!, append ( L1, L2, L4).(1)
Goal
append(L1,[3|T],[1,2,3,4]). (2)
Процедури delete і delete1 – вилучають вказаний елемент із списку.
Процедура delete1 – вилучає вказаний елемент, який перший зустрівся в списку.
Domains
list=integer*
Predicates
delete1(integer, list, list)
Goal
delete1 ( 2, [ 1, 2, 2 ], L ).
Clauses
delete1( _, [ ], [ ] ):-!. (1)
delete1( X, [X | L1 ], L1 ):-!. (2)
delete1( X, [ H | L1], [H | L2 ] ):- delete1(X, L1, L2 ). (3)
Вилучити першу 2, що зустрілася у списку [1,2,2]. Результат розміщується у змінну L=[1,2].
Перше умовне твердження істинне, якщо елемент не знайдено. Результат співпадає з вхідним списком.
Друге правило вилучає знайдений елемент. Залишок списку переноситься у новий список.
Третє правило переносить голову списку у новий список, якщо вона не співпадає з елементом, який вилучається. Після цього продовжується пошук елементу, який вилучається.
Процедура delete2 – вилучає всі елементи списку, що дорівнюють вказаному.
Domains
list=integer*
Predicates
delete2(integer, list, list)
Goal
delete2 ( 2, [ 1, 2, 2 ], L ).
Clauses
delete2( _, [ ], [ ] ):-!. (1)
delete2(X, [ X | L1 ], L2 ):-!, delete2( X, L1,L2 ). (2)
delete2( X, [ H | L1], [ H | L2 ] ):- delete2( X, L1,L2 ). (3)
Процедура delete2 відрізняється від процедури delete1 тим, що після того, як вилучено вказаний елемент, вона продовжує пошук вказаного елемента у хвості списку і вилучає всі елементи, що дорівнюють вказаному.
3.2.2 Виконайте завдання свого варіанту за № в журналі.
Продумайте, які стандартні процедури ви можете використати у вашій програмі. Пам'ятайте, що ваша програма буде компактна, якщо ви будете використовувати можливості Прологу - відокремлювати перший елемент від списку у голові правила.
Налагодьте вашу програму за допомогою трасування. Під час трасування переконайтесь, що ваша програма не має зайвих розв'язків або не виконує непотрібних дій.
