Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Логическое программирование1 / 9_Лабораторна_робота_ЛП_2012-13.doc
Скачиваний:
14
Добавлен:
07.02.2016
Размер:
186.37 Кб
Скачать

2.3. Приклад 3 роботи зі списками (рекурсивна поелементна обробка заданого списку, з формуванням на його основі нового списку)

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

У наведеному далі лістингу 9_3 представлено приклад Пролог-програми, що здійснює на основі методу рекурсії наступні дії:

– поелементну обробку заданого списку без внесення до нього змін (виділення зі списку окремих елементів та їх перевірку на відповідність певним умовам);

– застосування до виділених елементів початкового списку певних перетворень (залежно від результатів виконаної перевірки) та формування нового списку, що складається зі змінених елементів.

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

– позитивні числа потрібно перетворити на від'ємні;

– для нульових значень не треба здійснювати жодних дій;

– від'ємні числа потрібно перетворити на позитивні.

Розглянемо два типові випадки (для порожнього та непорожнього списків):

– результатом перетворення порожнього списку має бути також порожній список;

– якщо список непорожній, то слід рекурсивно виконувати відокремлення голови поточного списку, її обробку та розглядати отриманий результат як голову списку-результату.

Прокоментуємо основні правила Пролог-програми.

Правило «Обробка порожнього списку має дати в результаті також порожній список» набуде наступного вигляду:

inverting ([ ], [ ]):- !.

Правило «Якщо список непорожній, то слід відокремити його голову, обробити її та додати в якості голови до списку-результату», має наступний вигляд:

inverting ([H | T], [Inv_H | Inv_T]):-

processing (H, Inv_H),

inverting (T, Inv_T).

Предикату processing, який виконує дії з обробки елементу списку залежно від його знаку, відповідають два речення, оскільки треба розглянути два варіанти (ненульове та нульове значення елементу списку):

processing (0, 0):- !.

processing (H, Inv_H):- Inv_H = -H.

Результат роботи Пролог-програми має наступний вигляд:

Inv_List = [2, 1, 0, -1, -2]

% Sheet 9_3. Primer 3 on the creating and recursive processing for list

DOMAINS

intlist=integer*

PREDICATES

inverting (intlist, intlist)

processing (integer, integer)

CLAUSES

inverting ([ ], [ ]):- !.

inverting ([H | T], [Inv_H | Inv_T]):-

processing (H, Inv_H),

inverting (T, Inv_T).

processing (0, 0):- !.

processing (H, Inv_H):- Inv_H = -H.

GOAL

inverting ([-2, -1, 0, 1, 2], Inv_List),

write("Inv_List = ", Inv_List).

2.4. Приклад 4 роботи зі списками (рекурсивна перевірка належності елементу до заданого списку)

У наведеному далі лістингу 9_4 представлено приклад Пролог-програми, що визначає факт належності деякого елементу до заданого списку.

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

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

– ознакою наявності розшукуваного елементу в заданому списку є успішне доведення мети Пролог-програми;

– якщо мету Пролог-програми не вдалося довести, то фіксується, що розшукуваний елемент відсутній у списку.

Прокоментуємо основні правила Пролог-програми.

Перша частина правила member має наступний вигляд:

member (Elem, [Elem | _]):- !.

Наведене вище речення Прологу відображає наступні логічні співвідношення:

– розшукуваний елемент знайдено, оскільки його значення співпало зі значенням голови списку;

– хвіст списку позначено анонімною змінною, оскільки тепер конкретне значення хвоста списку не є важливим.

Друга частина правила member має наступний вигляд:

member (Elem, [_ | T]):- member (Elem, T).

Наведене вище речення Прологу відображає наступні логічні співвідношення:

– якщо розшукуваний елемент ще не знайдено, то його намагаються знайти в хвості списку;

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

Предикат search використовується для наступних двох цілей:

1) для того, щоб повідомити про конкретні результати проведеного пошуку;

2) для того, щоб програма завжди (при будь-якому результаті пошуку) завершувала своє виконання з успіхом.

Відповідно, реалізацію предикату search буде сформовано з наступних двох речень:

search (Elem, List):- member (Elem, List), !,

write ("Element is find !").

search (_, _):- write ("Element dont find !").

Результат роботи Пролог-програми має наступний вигляд:

Element is find !

% Sheet 9_4. Primer 4 on the creating and recursive processing for list

DOMAINS

strlist=string*

PREDICATES

member (string, strlist)

search (string, strlist)

CLAUSES

member (Elem, [Elem | _]):- !.

member (Elem, [_ | T]):-

member (Elem, T).

search (Elem, List):-

member (Elem, List), !,

write ("Element is find !").

search (_, _):-

write ("Element dont find !").

GOAL

Cities = ["Kiev", "Odessa", "Kherson", "Nikolaev", "Kahovka"],

City = "Kherson",

search (City, Cities).