
- •2. Описание лабораторных работ по функциональному программированию на языке лисп
- •2.1. Краткие теоретические сведения по программированию на языке Лисп
- •Основные функции обработки списков
- •Присваивание значений
- •Предикаты
- •Определение функций
- •Ввод-вывод
- •2.2. Лабораторная работа по теме «Знакомство с основными понятиями в системе программирования Лисп»
- •2.3. Лабораторная работа по теме «Решение задач с ветвлением в системе программирования Лисп»
- •2.4. Лабораторная работа по теме «Реализация рекурсии на языке Лисп»
- •2.5. Лабораторная работа по теме «Обработка списков на языке программирования Лисп»
Основные функции обработки списков
К операциям выделения отдельных частей списков и создания из них новых структур сводятся многие алгоритмы обработки символьной информации. Основными функциями, на основе которых выполняются указанные действия, являются встроенные функции CAR, CDR и CONS. Эти функции определяются на основе функций CAR, CDR, CONS. Список - частный случай точечной пары, то применимы функции, аргументы которых заданы точечными парами.
Для доступа к первому элементу точечной пары или списка применяется функция CAR. К примеру:
(саr '(а . b)) ─>А
(саr '(а b)) ─> А
Здесь апостроф, обозначает вызов специальной формы QUOTE , которая блокирует вычисление значения s ─ выражения (а . b) или (а b). Если этого не сделать, то Лисп-интерпретатор (EVAL) предпримет попытку вычислить эти s-выражения. В соответствии с правилами работы интерпретатора, первый элемент s-выражения воспринимается как имя функции. Однако, на самом деле, функции с именем А нет. Поэтому возникает ошибка: UNDEFINED-FUNCTION (неопределенная функция). Применение функции QUOTE сообщает Лисп ─ системе, что аргументы функции CAR не подлежат вычислению и представляют самих себя.
Для выделения второго элемента точечной пары применяется функция CDR. К примеру:
>(cdr'(a.b))
В
>(cdr'(a b))
(В)
В первом случае возвращается атом В, а во втором случае - список, содержащий атом В. Этот результат объясняется тем, что список (А В) в точечной записи имеет вид (А . (В . NIL)). Функция CDR возвращает второй элемент точечной пары ( В . NIL), т.е. (В).
Функция CAR и CDR определены только для точечных пар. Для аргументов атомов результаты функций CAR и CDR неопределенны.При попытке вызова (саг 'а) формируется сообщение об ошибке. Для выделения произвольных элементов списка используются композиции функций CAR и CDR. К примеру:
> (саг (саг '((а b) (b с))))
А
> (car (cdr (cdr '(1 2 3))))
3
Композиции функций CAR и CDR встречаются довольно часто, поэтому для них введены специальные имена:
(car (car х)) < ─ >(сааr х),
(car (cdr х)) < ─ > (cadr x),
(cdr (car x)) < ─> (cdar x),
(cdr (cdr х)) < ─ > (cddrx),
…
(cdr (cdr (cdr (cdr x)))) < ─ > (cddddr x).
В Коммон Лиспе для выделения отдельных элементов списков можно использовать более удобные имена функций, отражающие суть выполняемой операции. Например:
REST ─ эквивалентна CDR, возвращает хвост вписка;
FIRST ─ эквивалента CAR, возвращает первый элемент вписка;
SECOND ─ эквивалентна CADR, возвращает второй элемент списка;
THIRD ─ эквивалентна CADDR, возвращает третий элемент списка и т.д.;
TENTH ─ возвращает десятый элемент списка. Имена указанных функций соответствуют порядковым числительным английского языка.
Для создания точечной пары из s ─ выражений в Лиспе применяется функция CONS (конструктор):
(cons 'а 'b) ─ > (А . В)
Конструирование списков с помощью функции CONS осуществляется последовательными вызовами:
(cons ('х (cons 'у (cons 'z NIL)))) ─ > (X Y Z)
Здесь сначала строится точечная пара (Z . NIL), затем точечная пара -(Y . (Z . NIL)), а в конце - точечная пара (X .(Y . (Z . NIL))), которая и представляет список (X Y Z). Таким образом, функция CONS включает очередной элемент в начало списка, представленного ее вторым аргументом. В Лиспе имеется функция LIST с произвольным числом аргументов, которая упрощает задачу создания списков:
(list 1 'b 'с) ─ > (1 В С)
Списки можно также создавать из других списков путем их объединения. Для этого применяется функция APPEND. К примеру,
(append '(1 2 а) '(b 4 5)) ─ > (1 2 А В 4 5)
В Лиспе имеется ряд других полезных функций для обработки списков:
LAST ─ выделяет последний элемент списка (результат - список);
NTH ─ выделяет n-й элемент списка;
SUBST ─выполняет замену элементов в списке;
BUTLAST ─ выделяет список без последних элементов;
MEMBER ─ проверяет принадлежность элемента списку;
LENGTH ─вычисляет длину списка;
REVERSE ─ выполняет обращение списка;
ADJOIN ─добавляет элемент в множество, представленное списком;
REMOVE ─ удаляет элемент из списка.