Введение в программирование на Лиспе. Учебное пособие
.pdf
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
Пример 3.3.
Любое S-выражение может быть построено из атомов с помощью CONS и любая его часть может быть выделена с помощью CAR-CDR.
Упражнение 3.3. Нарисуйте диаграммы для следующих S-выражений:
((A . B) . C)
((A . B) . (D . C))
((A . B) . (D . (C . E)))
Расширение типа данных, допускаемых в качестве второго аргумента " CONS ", ни в малейшей степени не усложняет реализацию этой функции, равно как и реализацию функций " CAR " и " CDR ", зато их описания становятся проще:
CONS - Функция, которая строит бинарный узел и заполняет его парой объектов, являющихся значениями пары ее аргументов. Первый аргумент размещается в левой части бинарного узла, а второй - в правой.
CAR – Функция, обеспечивающая доступ к объектам, расположенным слева от точки в точечной нотации, т.е. в левой части бинарного узла.
CDR - Функция, обеспечивающая доступ к объектам, расположенным справа от точки в точечной нотации, т.е. в правой части бинарного узла.
Таблица 3.2. Элементарные функции над произвольными S- выражениями
31
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
Функция |
|
Аргументы |
|
Результат |
|
|
|
||
|
|
Конструирование структур данных |
||
|
|
|
|
|
CONS |
|
A и B |
|
(A . B) |
|
|
|
|
|
CONS |
|
(A . B) и C |
|
((A . B) . C) |
|
|
|
|
|
CONS |
|
A B |
|
(A . B) |
|
(Результат предыдущего CONS) |
|
||
CONS |
|
|
((A . B) . C) |
|
|
и C |
|
||
|
|
|
|
|
Доступ к компонентам структуры данных:
Слева
CAR
CAR
CDR
CDR
CDR
CAR
CDR
CAR
CONS
CAR
CONS
CDR
CONS
(A . B) |
|
A |
|
|
|
((A . B) . C) |
|
(A . B) |
Справа |
|
|
|
|
|
(A . B) |
|
B |
|
|
|
(A . (B . C)) |
|
(B . C) |
Обработка данных: |
||
|
|
|
(A . (B . C)) |
|
(B . C) |
Результат предыдущего CDR |
|
B |
|
|
|
|
|
|
(A . C) |
|
C |
Результат предыдущего CDR |
|
Не определен |
|
|
|
|
|
|
A и B |
|
(A . B) |
Результат предыдущего CONS |
|
A |
|
|
|
|
|
|
A и B |
|
(A . B) |
Результат предыдущего CONS |
|
B |
|
|
|
Тождества:(на произвольных объектах)
Два произвольных объекта x и y. Исходный объект x
32
Л.В. Городняя, Н.А. Березин |
|
Введение в программирование на Лиспе |
||||
|
CAR |
|
Результат предыдущего CONS |
|
(первый аргумент CONS ) |
|
|
|
|
|
|
|
|
CONS
CDR
CAR
CDR
CONS
ATOM
CDR
ATOM
EQ
Два произвольных объекта x и y. Исходный объект y
Результат предыдущего CONS. (второй аргумент CONS ) |
||
|
|
|
Произвольный составной |
|
|
объект x - не атом. |
|
|
Тот же самый объект x. |
|
Исходный объект x |
|
|
|
Результаты предыдущих CAR и |
|
|
CDR |
|
|
|
|
|
Предикаты:
Атомарность – неделимость
( A . B ) |
|
Nil - выполняет роль |
|
ложного значения |
|
|
|
|
|
|
|
( A . B ) |
|
B |
Результат предыдущего CDR |
|
T |
|
|
|
Равенство |
|
|
|
|
|
(A . B) (A . B) |
|
Не определен |
Точечная нотация может точно представлять логику хранения любых структур данных в памяти и доступа к компонентам структур данных. В виде списков можно представить лишь те S-выражения, в которых при движении вправо в конце концов обнаруживается атом Nil, символизирующий завершение списка.
Упражнение 3.4. Посмотрите, что делает Лисп-система с ниже приведенными выражениями, сравнивая результаты с данными из таблицы 3.2:
(CONS 'Head 'Tail ) (CAR '(Head . Tail)) (CDR '(Head . Tail))
33
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
(ATOM 'Atom) (ATOM ())
(ATOM (CAR '(Head . Tail))) (EQ Nil ())
Атом Nil, рассматриваемый как представление пустого списка (), выполняет роль ограничителя в списках. Одноэлементный список (A) идентичен S-выражению (A . Nil). Список (A1 A2 … Ak) может быть представлен как S-выражение вида:
(A1 . (A2 . ( … . (Ak . Nil) … ))).
В памяти это фактически одна и та же структура данных.
Таблица 3.3. Соответствие списков и равнозначных им S-выражений
List-notation - списочная запись Dot-notation - точечная запись того же
объекта |
|
объекта |
(A B C ) |
|
(A . (B . (C . Nil))) |
|
|
|
((A B) C ) |
|
((A . (B . Nil)) . (C . Nil)) |
|
|
|
(A B (C E)) |
|
(A . (B . ((C . (E . Nil)). Nil))) |
|
|
|
(A) |
|
(A . Nil) |
|
|
|
((A)) |
|
((A . Nil) . Nil) |
|
|
|
(A (B . C)) |
|
(A . ((B . C) . Nil)) |
|
|
|
(()) |
|
(Nil . Nil) |
|
|
|
(A B . C) |
|
(A . (B . C)) |
Для многошагового доступа к отдельным элементам такой структуры удобно пользоваться мнемоническими обозначениями композиций из многократных CAR-CDR. Имена таких композиций устроены как цепочки из " a " или " d ", задающие маршрут движения из шагов CAR и CDR соответственно, расположенный между " c " и " r ". Указанные таким способом CAR-CDR исполняются с ближайшего к аргументу шага, т.е. в порядке, обратном записи.
Таблица 3.4. Примеры многошагового доступа к элементам структуры.
Композиции CARВычисляются в порядке, обратном
34
Л.В. Городняя, Н.А. Березин |
|
Введение в программирование на Лиспе |
||||
|
|
|
CDR |
|
записи: |
|
|
|
|
|
|
|
|
|
CAAR |
|
((A ) B C) |
|
A |
|
|
|
|
|
|
|
|
|
CADR |
|
(A B C) |
|
B - CDR, затем CAR |
|
|
|
|
|
|
|
|
|
CADDR |
|
(A B C) |
|
C - (дважды CDR), затем CAR |
|
|
|
|
|
|
|
|
|
CADADR |
(A (B C) D) |
|
C - два раза:(CDR, затем CAR) |
|
|
Упражнение 3.5. Посмотрите, что делает Лисп-система с ниже приведенными выражениями, сравнивая результаты с данными из таблицы 3.3:
(cAAr '((A) B C) )
(cADr '(A B C))
(cADDr '(A B C) )
(cADADr '(A (B C) D))
Таблица 3.5. Clisp: Функции для работы с данными
(Append Список Сцепляет списки, полученные как аргументы
… )
(Assoc Атом А- Находит в А-списке пару, левая часть которой –
список) |
|
Атом |
Atom |
|
Проверка на атомарность |
|
|
|
Car |
|
Первый элемент списка или левый элемент |
|
структуры |
|
|
|
|
Cdr |
|
Результат удаления первого элемена из списка или |
|
правый элемент структуры |
|
|
|
|
Cons |
|
Создание узла из двух элементов |
|
|
|
(Eq Данное1 |
|
Истина при идентичных данных |
Данное2) |
|
|
|
|
|
(Equal |
|
|
Структура1 |
|
Истина при эквивалентных структурах |
Структура2 ) |
|
|
(Delete Объект Строит копию Списка без заданного объекта
Список )
(Intersection Пересечение списков
Список … )
Последний элемент структуры, представляющей
35
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
(Last Список ) список. Можно задавать длину завершающего отрезка списка.
(Length Список |
|
Длина списка |
) |
|
|
|
|
|
(List Форма … |
|
Строит список из значений Форм |
) |
|
|
|
|
|
(Member Объект |
|
Ищет Объект в Списке |
Список ) |
|
|
|
|
|
(Null Форма) |
|
Истина для Nil |
|
|
|
(Pairlis Атомы |
|
Пополняет А-список парами из Атомов и |
Данные А- |
|
значений, соответствующих Данных. |
спиок) |
|
|
|
|
|
(Reverse |
|
Копия Списка с обратным порядком элементов |
Список ) |
|
|
|
|
|
(Set- |
|
|
difference |
|
Разность множеств, представленных Списками |
Список … ) |
|
|
(Sort Список Предикат )
(Sublis А-
список Структура )
(Subst Новое Старое Структура )
(Union Список … )
Упорядочивает Список согласно Предикату
Преобразует Структуру согласно А-списку методом подстановки данных вместо связанных с ними атомов.
Преобразует Структуру, заменяя Старое на Новое.
Объединение множеств, представленных Списками.
Выводы:
Список – это перечень произвольного числа элементов, разделенных пробелами, заключенный в круглые скобки. Элементы списка могут быть любой природы.
S-выражение - это или атом или заключенная в скобки пара из двух S-выражений, разделенных точкой. Список – частный случай S-выражения.
36
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
Любое S-выражение может быть построено из атомов с помощью CONS и любая его часть может быть выделена с помощью CARCDR.
Для изображения S-выражений используют различные нотации: графическую, точечную и списочную.
Базис Лиспа содержит элементарные функции CAR, CDR, CONS,
EQ, ATOM.
1)Дж. Мак-Карти назвал их S-выражениями - Symbolic expressions
2)Латинский шрифт используется исключительно ради простоты набора текстов. Вполне допустима кириллица
37
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
Запись Лисп-программ
Теперь рассмотрим правила записи программ на Лиспе. Такие правила различны для обычных и специальных функций. Для Лиспа характерно предпочтение рекурсивных функций. Функции могут иметь названия или быть безымянными, сконструированными для разового использования.
Основные понятия, возникающие при написании программ – это переменные, константы, выражения, ветвления, вызовы функций и определения. Все они представимы с помощью списков.
1.Самая простая форма выражения - это переменная. Имя переменной может быть представлено как атом. Переменная – это атом, имеющий значение.
X
N Variable1
Переменная2 LongSong
ДолгаяПесня
Пример 4.1.
1.Названия функций, как и имена переменных, изображаются с помощью атомов, для наглядности можно предпочитать заглавные буквы.
CONS
CAR
CDR
ATOM
EQ
Пример 4.2.
1.Все более сложные формы в Лиспе понимают как применение функции к ее аргументам (вызов функции). Аргументом функции
38
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
может быть любая форма. Список, первый элемент которого – представление функции, остальные элементы - аргументы функции, – это основная конструкция в Лисп-программе.
Формат:
(функция аргумент1 аргумент2 ... )
(CONS 1 2 )
Пример 4.3.
Обычно кроме базовых средств в язык включается и набор наиболее употребимых базовых операций над числами и другими данными. Если введены числа, то введены и традиционные арифметические операции, но форма их применения подчинена общим правилам:
(+ 1 2 3 4) ;; = 10
1.Композиции функций естественно строить с помощью вложенных скобок.
Формат:
(функция1 (функция2 аргумент21 аргумент22 ... ) аргумент2 ... )
(CAR (CONS 1 2 ) )
(CONS (CAR (CONS 1 2 ) ) (CDR (CONS 3 4 ) ))
Пример 4.4.
Этих правил достаточно, чтобы более ясно выписать основные тождества Лиспа, формально характеризующие элементарные функции
CAR, CDR, CONS, ATOM, EQ над S-выражениями:
(CAR (CONS x y)) = x (CDR (CONS x y)) = y (ATOM (CONS x y)) = Nil
(CONS (CAR x) (CDR x)) = x для неатомарных x.
39
Л.В. Городняя, Н.А. Березин |
Введение в программирование на Лиспе |
(EQ x x) = T если x атом |
|
(EQ x y) = Nil если x и y различимы |
|
Любые композиции заданного набора функций над конечным множеством произвольных объектов можно представить таким способом, но класс соответствующих им процессов весьма ограничен и мало интересен. Организация более сложного класса процессов требует более детального представления в программах соответствия между именами и их значениями или определениями, изображения ветвлений и объявления констант.
Специальные функции
1.Константа представляется как аргумент специальной функции QUOTE в виде списка:
(QUOTE (C O N S T ))
Пример 4.5. Список из атомов объявлен константой
Используется и сокращенная запись – апостроф перед произвольным данным.
'(C O N S T )
Пример 4.6.
В зависимости от контекста одни и те же объекты могут выполнять роль переменных или констант, причем значения и того, и другого могут быть произвольной сложности. Если объект выполняет роль константы, то для объявления константы достаточно заблокировать его вычисление, то есть как бы взять его в кавычки (quotation), выделяющие буквальное использование фраз, не требующее обработки. Для такой блокировки вводится специальная унарная функция QUOTE, предохраняющая свой аргумент от вычисления.
|
(QUOTE |
|
Константа A объявлена. |
|
|
A) |
|
|
|
|
|
|
|
|
|
(QUOTE |
|
|
|
|
|
|
|
|
40
