Page 37 - 4800
P. 37
Приклад такого підходу реалізований у програмі 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).
4.4 Процедури обробки списків
Списки можна застосовувати для представлення множин, хоча і є деяке
розходження між цими поняттями. Порядок елементів множини не важливий, у той час
як для списку цей порядок має значення. Крім того, той самий об'єкт R списку може
зустрітися декілька раз. Однак, найбільш використовувані операції над списками
аналогічні операціям над множинами. Це перевірка об’єкту на належність множині,
об’єднання двох множин, видалення з множини деякого об’єкта.
Належність до списку. Представимо відношення належності у вигляді
member(R, L), де R – терм, a L – список. Ціль member(R, L) істинна, якщо терм R
зустрічається в L. Задача перевірки входження терму в список формулюється у вигляді:
Гранична умова: Терм R знаходиться в списку, якщо R є голова списку L.
Рекурсивна умова: Терм R знаходиться в списку, якщо R належить хвостові L.
Один з варіантів Пролог-процедури можна представити в наступному виді:
member(R,L):-L=[H|Т], H=R.
member(R,L):- L=[H|Т], member(R,T).
Ціль L=[H|Т] у тілі обох правил служить для того, щоб розділити список L на
голову і хвіст. Можна поліпшити процедуру, якщо врахувати той факт, що Пролог
спочатку зіставляє з метою заголовок правила, а потім намагається погодити його тіло.
Тоді поліпшений варіант цієї ж процедури може бути записаний у виді:
member(R, [R |_]).
member(R,[_ | Т]) :- member(R, Т).
Використання анонімних змінних (_) викликане тим, що при застосуванні
першого правила нас не цікавить хвіст списку, а при застосуванні другого – голова
списку.
Як приклад розглянемо роботу процедури при виконанні мети:
member(d,[a,b,d,c]).
Мета починає зіставлятися з першого правила, але тому що d це не а, то
відбувається відкат до другого правила.
Змінна Т одержує значення [b,d,c], і породжується нова мета: member(d,[b,d,c]).
Тому що перше правило не уніфікується з метою, відбувається повторне зіставлення
другого правила і виділення нового хвоста списку.
Поточною метою стає member(d,[d,c]). Використання першого правила
приводить до того, що елемент, який перевіряється, d зіставляється з головою списку.
[d,c]. Перше правило стає істинним, тобто ціль досягнута.
Якщо вихідна мета member(d,[a,b,c,e]), то процес зіставлення з другим правилом
буде рекурсивно повторюватися дотих пір, поки не буде досягнута мета member(d,[]).
37