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

4.2 Використання списків у Пролог-програмах

Застосування списків у програмі відображається у трьох її розділах. Домен списку повинен бути описаний у секції domains, а працюючий зі списком предикат – у секції predicates. Нарешті, потрібно задати сам список у секції clauses або goal. Розглянемо приклад простої програми, що використовує у своєму складі список.

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

domains

list_sеаsоn=season*

season=string

pedicates

year(list_season)

clauses

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

Ця програма містить список пір року. Найменування сезонів є даними символьного типу і являють собою домен елементів списку. Відмінною рисою в описі списку є наявність символу зірочки (*) після імені домену елементів.

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

Розглянемо ще три приклади програм. Програма 4.2 показує можливість використання в предикатах спискових структур разом з іншими доменними структурами (предикат office містить цілочисльний і списковий домени).

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

domains

number=integer

worker=string

list_worker=worker*

predicates

office(number,list_worker)

clauses

office(101,["Кардаш", "Петренко", "Маслов"]).

office(211,[ "Денега" ]).

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

domains

number,salary=integer

name=string

member=worker(name,salary)

list_worker=member*

predicates

office(number,list_worker)

clauses

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

office(211,[ worker("Денега", 400)]).

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

domains

name = string

list_worker = name*

number = integer

office = office(number , list_worker)

list_office = office*

predicates

all_office( list_offlce )

clauses

all_office([office(101,["Кардаш","Петренко","Маслов"]), office(211,["Денега"]) ]).

Програма 4.3 ілюструє той факт, що елементами списку можуть бути не тільки стандартні домени, але і будь-які, обумовлені користувачем складні структури. Так, наприклад, у даній програмі елементами списку list_worker є екземпляри структури worker(name, salary).

Програма 4.4 демонструє, що елементами спискових структур можуть бути і самі списки. Так, елементом списку list_office є структура office(number , list_worker), одним з аргументів якої є список.

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

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

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

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

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

/* програма 4.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).

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

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

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

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

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

/* програма 4.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:- 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).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]