Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
49
Добавлен:
05.03.2016
Размер:
1.28 Mб
Скачать

7.3. Найпростіші процедури роботи зі списками

У завданні 1 зовнішня мета year(All) забезпечувала присвоєння змінній All усього списку в цілому. Навпаки, мета year(_,Х,_,_) дозволяла витягнути зі списку усього лише один елемент. Однак, у цьому випадку було потрібне точне знання числа елементів у списку. Якщо задати мету у виді year([Х,Y]), то вона не буде досягнута, через невідповідність кількості елементів у списку і цільовому твердженні.

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

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

/* програма 7.5 */

domains

list_season=season*

season=string

predicates

year(list_season)

print_list(list_season)

goal

year(L), print_list(L).

clauses

year([“зима”, “весна”, “літо”, “осінь”]).

print_list([]).

print_list([Х|Y]):- write(X), nl, print_list(Y).

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

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

print_list([]):- L=[Х|Y], write(X), nl, print_list(Y).

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

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

Завдання 3.

Доробіть програму 7.1 до вигляду 7.5 і запустіть на виконання. Використовуючи trace print_list(), познайомтеся з процесом поділу списку в процесі виконання рекурсії.

Однак, внутрішня мета програми обмежує можливі дії по модифікації даних у базі: додаванню, пошукові, виключенню і т.д.

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

Приклад такого підходу реалізований у програмі 7.6, з використанням предиката show_worker.

/* програма 7.6 */

domains

number,salary=integer

name=string

member=worker(name,salary)

list_worker=member*

predicates

office(number,list_worker)

print_list(list_worker)

show_workеr

clauses

show_worker:- makewindow(l,7,15, “Службовці” ,5,10,12,30), cursor(2,1), write(“Введіть номер відділу -> “), readint(Otd), office(Otd,L), print_list(L), readchar(_).

office(101,[worker(“Кардаш”,500), worker(“Петренко”,300), worker(“Маслов”,200)]).

office(211,worker(“Денега”, 400)]).

print_list([]).

print_list([X|Y]):- write(X),nl, print_list(Y).

Завдання 4.

Доробіть програму 7.3 до вигляду 7.6, розберіться в ній і запустіть на виконання.