Опубликован: 21.08.2007 | Доступ: свободный | Студентов: 1805 / 194 | Оценка: 4.23 / 3.74 | Длительность: 15:37:00
Лекция 2:

Определение языков программирования

< Лекция 1 || Лекция 2: 1234 || Лекция 3 >

Универсальная функция

Интерпретация или универсальная функция - это функция, которая может вычислять значение любой формы, включая формы, сводимые к вычислению произвольной заданной функции, применяемой к аргументам, представленным в этой же форме, по доступному описанию данной функции. (Конечно, если функция, которой предстоит интерпретироваться, имеет бесконечную рекурсию, интерпретация будет повторяться бесконечно.)

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

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

  • Атомарное выражение обычно понимается как переменная. Для него следует найти связанное с ним значение. Например, могут быть переменные вида "x", "elem", смысл которых зависит от контекста, в котором они вычисляются.
  • Константы, представленные как аргументы функции QUOTE, можно просто извлечь из списка ее аргументов. Например, значением константы ( QUOTE T ) является атом T, обычно символизирующий значение "истина".
  • Условное выражение требует специального механизма для предварительного вычисления предиката и выбора нужной ветви. Например, интерпретация условного выражения1Условные выражения такого вида были введены в математическую теорию вычислений Маккарти (1963)
    (IF  (ATOM x) x (first (CAR x) ) )
    должна обеспечивать выбор ветви в зависимости от атомарности значения переменной.
  • Остальные формы выражений рассматриваются по общей схеме как список из функции и ее аргументов. Обычно аргументы вычисляются, а затем вычисленные значения передаются функции для интерпретации ее определения. Так обеспечивается возможность писать композиции функций. Например, в выражении (first (CAR x)) внутренняя функция CAR сначала получит в качестве своего аргумента значение переменной x, а потом свой результат передаст как аргумент более внешней функции first.
  • Если функция представлена своим названием, то среди названий различаются имена встроенных функций, такие как CAR, CDR, CONS и т.п., и имена функций, введенные в программе, например first. Для встроенных функций интерпретация сама "знает", как найти их значение по заданным аргументам, а для введенных в программе функций - использует их определение, которое находит по имени.
  • Если функция использует лямбда-конструктор, то прежде чем его применять, понадобится связывать переменные из лямбда-списка со значениями аргументов. Функция, использующая лямбда-выражение,
    (LAMBDA (x)  (IF   (ATOM x) x  (first (CAR x) ))  )
    зависит от одного аргумента, значение которого должно быть связано с переменной x. В определении используется свободная функциональная переменная first, которая должна быть определена в более внешнем контексте.
  • Если представление функции начинается с LABEL, то понадобится сохранить имя функции с соответствующим ее определением так, чтобы корректно выполнялись рекурсивные вызовы функции. Например, предыдущее LAMBDA-определение безымянной функции становится рекурсивным, если его сделать вторым аргументом специальной функции LABEL, первый аргумент которой - first, имя новой функции.
    (LABEL first  (LAMBDA (x)   (IF  (ATOM x) x (first (CAR x) ))   ))

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

  • обработка структур данных ( cons, car, cdr, atom, eq );
  • конструирование функциональных объектов ( lambda, label );
  • идентификация объектов в контексте (имена переменных и названия функций);
  • управление логикой вычислений и границей вычислимости (композиции, quote, if, eval ).

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

PAIRLIS - функция аргументов x, y, al строит список пар соответствующих элементов из списков x и y и присоединяет их к списку al. Полученный список пар, похожий на таблицу с двумя столбцами, называется ассоциативным списком или контекстом. Такой список используется для связывания имен переменных и функций при организации вычислений интерпретатором.

(DEFUN pairlis (x y al) (IF (null x) al
      (CONS (CONS (CAR x)
                  ( CAR Y) )
                  (pairlis (CDR x)
                        (CDR y)
                             al)  ))
   
(pairlis '(A B C) '(u t v) '((D . y)(E . y))) = ((A . u)(B . t)(C . v)(D . y)(E . y))

ASSOC - функция двух аргументов, x и al. Если al - ассоциативный список, подобный тому, что формирует функция pairlis, то assoc выбирает из него первую пару, начинающуюся с x. Таким образом, это функция поиска определения или значения в контексте, реализованном как ассоциативный список.

(DEFUN assoc (x al) (IF 
        (equal x (CAAR al)) (CAR al)
                (assoc x (CDR al))   )

Частичная функция - рассчитана на наличие ассоциации.

(assoc 'B '((A . (m n)) (B . (CAR x)) (C . w) (B . (QUOTE T)))) = (B . (CAR x))
< Лекция 1 || Лекция 2: 1234 || Лекция 3 >
Федор Антонов
Федор Антонов

Здравствуйте!

Записался на ваш курс, но не понимаю как произвести оплату.

Надо ли писать заявление и, если да, то куда отправлять?

как я получу диплом о профессиональной переподготовке?

Илья Ардов
Илья Ардов

Добрый день!

Я записан на программу. Куда высылать договор и диплом?