Page 38 - 4800
P. 38

Жодне  з  правил  не  уніфікується  з  цією  метою  і,  тому  вихідна  мета  виявляється
            помилковою.
                   З’єднання  двох  списків.  Для  з’єднання  двох  списків  визначимо  відношення
            append(L1, L2, L3), де L1 – вихідний список, L2 – список, що приєднується (додається),
            a  L3  –  список,  одержуваний  при  їхньому  з’єднанні.  Задача  з’єднання  списків
            формулюється в такий спосіб:
                   Гранична умова: Приєднання списку L2 до [] дає той же список L2.
                   Рекурсивна  умова:  Список  L2  приєднується  до  хвоста  L1,  а  потім  попереду
            додається голова L1.
                   Тоді безпосередньо з постановки задачі можна написати процедуру виду:
                   аppend([], L2, L2).
                   append(L1, L2, L3):- L1=[H|Т], append(T, L2, X), L3=[H|X]
                   Однак, як і  в попередньому випадку, скористаємося тим, що  Пролог спочатку
            зіставляє  з  метою  заголовок  правила,  а  потім  намагається  погодити  його  тіло.  Тоді
            удосконалений варіант цієї ж процедури буде записаний у вигляді:
                   append([ ], L2, L2 ).
                   append([Н|L1], L2, [Н|L3]):- append(L1, L2, L3).
                   На запит append([a,b,c], [d,e], L) буде отримана відповідь L=[a,b,c,d,e], а на запит
            append([a,b],[c],[a,c,d]) відповіддю буде “ні”.
                   Дану процедуру можна також використовувати для пошуку в списку комбінацій
            елементів,  що  відповідає  деякій  умові,  що  задається  у  вигляді  шаблона.  Наприклад,
            можна знайти всі місяці, що передують даному, і всі, наступні за ним, сформулювавши
            таку мету:
                   Goal: append(X,[“квітень”|Y ], [“січень”, “лютий”, “березень”, “квітень”,
            “травень”, “червень”] )
                   X=[“січень”, “лютий”, “березень”, “квітень”]
                   Y=[“травень”, “червень”]
                   Видалення  елементу.  Для  видалення  елемента  Х  зі  списку  L  введемо
            відношення delete(X, L, L1), де L1 – скорочений список. Задача буде сформульована у
            виді:
                   Гранична умова: Якщо Х – голова, то результатом видалення буде хвіст списку.
                   Рекурсивна  умова:  Якщо  Х  знаходиться  в  хвості  списку,  тоді  його  варто
            видалити з хвоста списку.
                   delete(X, [X | Т], Т).
                   delete(X, [Y | T ], [Y, T1]):- delete(X, T, T1).
                   Одержання  n-го  терма  зі  списку.  Задача  доступу  до  заданого  номером
            елементу списку формулюється наступним чином:
                   Гранична умова: Перший терм у списку [H|] є Н.
                   Рекурсивну умову: N-й терм у списку [H|] є (N-1)-шим термом у списку Т.
                   term_in_list( [Н | _],1,Н ).
                   term_in_list([ _ |Т], N, X ) :- M=N-1, term_in_list(T, M, X).
                   Визначення довжини списку. Задача формулюється в такий спосіб:
                   Гранична умова: Довжина порожнього списку дорівнює нулеві.
                   Рекурсивна умова: Довжина списку [H|] на одиницю більше довжини списку Т.
                   list_len([],0).
                   list_len([_|T],Len):- list_len(T,Len1), Len = Len1+1.
                   У  предикаті  list_len  другий  аргумент  набуває  значення  рівне  довжині  списку.
            Якщо  другий  аргумент  є  зв'язаною  змінною,  то  йде  перевірка  на  її  збіг  з  довжиною
            списку.

                   4.5. Компонування даних у список

                   Часто при роботі з базами даних постає задача перетворення структур вихідних
            відносин для виконання тієї або інші операції над ними. Однією з таких задач є вибір
            даних із бази в список для наступної обробки.
                   У  складі  Прологу  для  цих  цілей  передбачений  стандартний  предикат  findall
            (знайти_усі). Даний предикат обчислює усі відповіді на запит і повертає їх у вигляді
            списку. Синтаксис цього предиката має вигляд:
                   findall( Variable, Predicat_expression, List_name) ,





                                                         38
   33   34   35   36   37   38   39   40   41   42   43