Опубликован: 19.03.2004 | Уровень: специалист | Доступ: платный
Лекция 6:

Свойства атомов и категории функций

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >

Представление структуры списка

В машине списки хранятся не как последовательности символов, а как структурные формы, построенные из машинных слов как частей деревьев, подобно записям в Паскале при реализации односвязных списков. При изображении структуры списка машинное слово рисуется как прямоугольник, разделенный на две части: адрес и декремент

структура списка

Рис. 1.1. структура списка

Каждая из частей занимает фиксированное число разрядов, представляющее тэг и адрес. Если декремент слова "x" указывает на слово "y", то это можно выразить стрелками на схеме:

схема

Рис. 1.2. схема

Теперь можно дать правило представления S-выражений в машине. Представление атомов будет пояснено ниже. В тех случаях, когда машинное слово в адресе или декременте содержит указатель на атом, данный атом отобразится как запись в соответствующем прямоугольнике:

отображение атома в прямоугольнике

Рис. 1.3. отображение атома в прямоугольнике

Правило представления неатомных S-выражений — начало со слова, содержащего указатель на car выражения в адресе и указатель на cdr в декременте. Ниже нарисовано несколько схем S-выражений. По соглашению NIL обозначается как перечеркнутый по диагонали прямоугольник.

обозначение NIL

Рис. 1.4. обозначение NIL

вместо (A . B).

(A . B)

Рис. 1.5. (A . B)

Непосредственная польза от сопоставления графического вида с представлением списков в памяти поясняется при рассмотрении функций, работающих со списками, на следующем примере из [1]:

((M . N) X (M . N))
пример

Рис. 1.8. пример

Возможное для списков использование общих фрагментов ((M . N) X (M . N)) может быть представлено графически:

графическое представление

Рис. 1.9. графическое представление

В точности такую структуру непосредственно текстом представить невозможно, но ее можно построить с помощью одного из выражений выражений:

(LET ((a '(M . N))) (SETQ b (LIST a 'X a)) )
((LAMBDA (a) (LIST a 'X a) )'(M . N))

Циклические списки обычно не поддерживаются. Такие списки не могут быть введены псевдо-функцией read, однако они могут возникнуть как результат вычисления некоторых функций, точнее, применения структуроразрушающих или деструктивных функций. Печатное изображение таких списков имеет неограниченную длину. Например, структура

структура

Рис. 1.10. структура

может распечатываться как ( A B C A B C ... ).

Преимущества структур списков для хранения S-выражений в памяти:

  1. Размер и даже число выражений, с которыми программа будет иметь дело, можно не предсказывать. Кроме того, можно не организовать для размещения выражений блоки памяти фиксированной длины.
  2. Ячейки можно переносить в список свободной памяти, как только исчезнет необходимость в них. Даже возврат одной ячейки в список имеет значение, но если выражения хранятся линейно, то организовать использование лишнего или освободившегося пространства из блоков ячеек трудно.
  3. Выражения, являющиеся продолжением нескольких выражений, могут быть предоставлены только однажды.

Ниже следует простой пример, иллюстрирующий точность построения структур списка. Показаны два типа структур списка и описаны на Лиспе функции для преобразования одного типа в другой.

Предполагается, что дан список вида

L1 = ((A B C)(D E F ) ... (X Y Z))

представленный как

точность построения структр списка

Рис. 1.11. точность построения структр списка

и нужно построить список вида

L2 = ((A (B C))(D (E F)) ... (X (Y Z)))

представленный как

список вида

Рис. 1.12. список вида

Рассмотрим типичную подструктуру (A (B C)) второго списка.

Она может быть построена из A, B и C с помощью

(CONS 'A (CONS (CONS 'B (CONS 'C NIL)) NIL))

или, используя функцию list, можно то же самое записать как

(LIST 'A (LIST 'B 'C))

В любом случае дан список x из трех атомов x = (A B C), аргументы A, B и C, используемые в предыдущем построении, можно найти как

A = (CAR x)
B = (CADR x)
C = (CADDR x)

Первый шаг в получении L2 из L1 — это определение функции GRP, строящей (X (Y Z)) из списка вида (X Y Z).

(GRP x) = (LIST (CAR x) (LIST (CADR x) (CADDR x)))

Здесь GRP применяется к списку L1 в предположении, что L1 заданного вида.

Для достижения цели новая функция MLTGRP определяется как

(MLTGRP L) = (COND ((NULL L) NIL)
      (T (CONS (GRP (CAR L)) (MLTGRP (CDR L)) )))

Итак, MLTGRP, применяемая к списку L1, перебирает (X Y Z) по очереди и применяет к ним GRP, чтобы установить их новую форму (X (Y Z)) до тех пор, пока не завершится список L1 и не построится новый список L2.

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >
Дарья Федотова
Дарья Федотова
Сергей Березовский
Сергей Березовский

В рамках проф. переподготовки по программе "Программирование"

Есть курсы, которые я уже прошел. Но войдя в курс я вижу, что они не зачтены (Язык Ассемблера и архитектура ЭВМ, Программирование на С++ для профессионалов). Это как?

Алина Ленкова
Алина Ленкова
Россия, Ставрополь, СФ МГУПИ, 2014
Валерий Ромашов
Валерий Ромашов
Россия