7.5 Списки и бинарные деревья
Рекурсивными могут быть не только правила, но и структуры данных. Тип
данных является рекурсивным, если он допускает структуры, содержащие такие же
структуры, как и они сами. Важным рекурсивным типом данных является список,
структура арности 2, второй аргумент которой является тоже списком.
Списки широко используются для представления деревьев синтаксического
разбора, карт городов, математических объектов (графов, формул, функций) и т.д.
В Прологе предусмотрена скобочная форма записи, при которой элементы
списка заключены в квадратные скобки и разделены запятой: [a, b, c, d] - список,
содержащий атомы a, b, c, d. Первый элемент называют "головой" списка, все
последующие - это "хвост" списка. Имеется также специальная форма для пре-
дставления списка с "головой" X и "хвостом" Y, где для разделения X и Y
используется вертикальная черта. Например, [X | Y] , списокƒ[a,ƒb,ƒc,ƒd] можно
записать как [a | [b,c,d]], допустима и такая запись [a, b | [c,d]].
[ ] - пустой список.
Пример 7.3
1. Определение принадлежности элемента к списку.
Предикат “элемент/2” состоит из двух утверждений. Первое – это факт: “элемент X является
элементом некоторого списка, если он совпадает с головным элементом этого списка”.
Второе – рекурсивное правило: “элемент X является элементом некоторого списка, если
элемент X является элементом списка, полученного из данного исключением головного
элемента”.
элемент(X, [X | L]).
элемент(X, [Y | L]):- элемент(X, L).
2. Слияние двух списков в третий.
Первый аргумент – исходный список, второй - добавляемый список, третий –
результирующий список.
слияние([], L, L]).
слияние([H|T], L, [H | NewList]):- слияние(T, L, NewList).
Если заданы любые два списка, то программа позволяет сформировать третий. Если заданы
все три списка, программа проверяет, является ли третий список результатом слияния первых
двух. Например, для выделения первого списка при известных других [c,d] и [a,b,c,d] можно
сделать такой запрос:
?- слияние(X, [c,d], [a,b,c,d]).
3. Исключение из списка элемента.