Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции ФЛП.doc
Скачиваний:
18
Добавлен:
27.05.2015
Размер:
632.83 Кб
Скачать

2.4 Трассировка функций в muLisp.

Язык программирования muLisp для трасировки использует программу debug.lsp, которая загружается в среду Лиспа. Для того, чтобы разрешить трасировку функции <func>, необходимо вызвать функцию (TRACE <func>). Если после этого вызвать функцию func с параметрами, то на экране отобразится путь выполнения функции. На каждом шаге будет выводиться имя функции и список фактических параметров. После выполнения функции на экран выводится значение функции. Команда (UNTRACE-FUNCTION <func>) запрещает трасировку функции <func>. Если в теле функции <func> существует вызов других функций, и мы хотим увидеть их трассировку, необходимо разрешить их трассировку.

Переменная echo переключает вывод трассы. По умолчанию ее значение равно NIL и трасса отображается только на экране. Если предоставить echo значение T и открыть соответствующий файл, результаты трассирования будут отображаться как на экране, так и в указанном файле.

Если вывод трассы происходит очень быстро, для временной остановки трассы можно использовать <CTRL-S>.

Например, рассмотрим трассирование функции APPEND (слияние двух списков). После вызовов функций командами

$ (setq echo T) (wrs 'ddd.dat) (TRACE ‘APPEND)

$ (APPEND '(q w e) (r t y u))

на экране и в файле ddd.dat отобразится трасса:

APPEND [(Q W E), (R T Y U)]

APPEND [(W E), (R T Y U)]

APPEND [(E), (R T Y U)]

APPEND [NIL, (R T Y U)]

APPEND = (R T Y U)

APPEND = (E R T Y U)

APPEND = (W E R T Y U)

APPEND = (Q W E R T Y U)

(Q W E R T Y U)

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

(CDR 'CALLCOUNT)

выдает на экране все отмеченные функции вместе со счетчиком вызовов каждой из них.

2.4 Определение функций в лисПе

В языке ЛИСП предусмотрено более чем триста встроенных функций, подобных базовым. Но независимо от их количества всегда возникает необходимость в новых функциях, определенных пользователем. Назначить имя и определить новую функцию можно с помощью специальной формы DEFUN (define function). Конструкция DEFUN имеет следующую структуру

(DEFUN <имя функции> (список формальных параметров)

<тело функции>

)

Тело функции состоит из одного или нескольких последовательных s-выражений (заданий). Описание функции должно всегда предшествовать обращению к ней (вызову). Так, функция, которая проверяет, является ли данный объект пустым списком, может быть определена так

(DEFUN NULL (obj)

(EQL obj NIL)

)

Ее вызов имеет вид

(NULL ‘(a b c d)) F (NULL (CDR ‘(f))) T

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

Если задание является атомом или его первый элемент является атомом, то такая задача называется простой. Например,

(CONS 'NR LST).

Если первый элемент списка, который описывает задание, не является атомом, то такое задание называется условным. Например,

((ATOM lst) (CONS expr lst)).

В условном задании первый элемент списка обязательно является предикатом. Если значение предикату NIL, то значение задания становится равным NIL и Лисп переходит к выполнению следующего задания. Если предикат возвращает не NIL, происходит выполнение хвоста списка задания, а другие задания игнорируются. Если предикат возвращает Т, а хвост задания пустой, то результатом всей функции будет T.

Например,

(defun max-min (l)

((atom l) 0)

(setq a (max l))

(setq b (min l))

(- a b)

)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]