Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conspekt.doc
Скачиваний:
11
Добавлен:
31.08.2019
Размер:
1.39 Mб
Скачать

2.2.15 Операции над строками битов

Приведенные ниже функции выполняют логические операции над битовыми представлениями своих аргументов.

(LOGAND2 X Y) <-> логическое "И"

(LOGOR2 X Y) <-> логическое "ИЛИ"

(LOGXOR2 X Y) <-> исключающее "ИЛИ"

Пример:

(LOGAND2 10 5) ==> (LOGAND2 1010 0101)->0

Т.е. операции производятся поразрядно над двоичными эквивалентами значений аргументов.

(LEFTSHIFT X Y) - первый аргумент есть восьмеричное число, второй - десятичное. Значение функции равно значению Х, сдвинутому на У разрядов влево (Y>0) или вправо (Y<0).

2.2.16 Функция cond

Число аргументов функции COND произвольно. Значения аргументов не вычисляются перед началом вычисления функции, а берутся в том виде, в каком они записаны. Более того, значения аргументов не могут быть вычислены. Каждый аргумент есть список из двух элементов:

(COND (P1 E1)(P2 E2)...(Pn En)), где

Р1, Р2, ... ,Рn- предикаты,

Е1, Е2, ... ,Еn- выражения на языке Лисп.

Порядок выполнения функции следующий. Если Р1=Т, то вычисляется значение выражения Е1 и оно возвращается в качестве результата, иначе происходит переход к анализу следующей скобки.Если Р2=Т, то вычисляем Е2 и т.д. Если все предикаты Рn-ложные, то результат- NIL.

Пример:

(COND ((ATOM A) NIL)(T T))->NIL

Если А - атом, то возвращается значение NIL, в противном случае, результат - Т.

2.2.17 Определяющее выражение функции

Можно ли сказать, что (COND ((ATOM A) NIL)(T T)) есть функция? Да, т.к. в зависимости от А это выражение позволяет вычислять требуемое значение. Но с другой стороны, вэтом выражение ничего не говорит о числе аргументов функции, их обозначении и задании их значений. Все эти сведения можно задать с помощью определяющего выражения функции. Определяющее выражение самостоятельно в программах не используется. Обычно его включают в состав функции, определяемой программистом.

Определяющее выражение задает тело такой функции. Формат определяющего выражения следующий:

(LAMBDA (X1 X2 ... Xn) e),

где X1,X2,...,Xn- аргументы определяемой функции,

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

Определим функцию из предыдущего примера:

(LAMBDA (X) (COND ((ATOM X) NIL) (T T) )

Или иной пример функции двух переменных:

(LAMBDA (U V) (CONS (CAR U) (CDR V))).

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

( (LAMBDA (X1 ... Xn) e) A1 ... An),

где А1,...,Аn - аргументы некоторой функции, имя которой заменено определяющим выражением.

Пример:

((LAMBDA(X)(COND((ATOM X)NIL)(T T)))'(B C))->T

2.2.18 Определяемые функции

Все описанные выше функции были встроенные. Говорят, что эти функции обладают свойством SUBR и FSUBR. Функции, задавамые программистом, называются определяемыми и вводятся с помощью определяющих выражений.

Определяемые функции могут быть двух типов: FEXPR и EXPR. У функций EXPR аргументы всегда вычисляются, следовательно, вместо аргументов можно писать другую функцию. У функций FEXPR вычисление аргументов блокируется за счет неявного применения функции QUOTE.

Функция называется обычной, если она имеет фиксированное число аргументов и если действия, указанные в ее определении, выполняются над значениями аргументов (CAR,CDR,CONS,ATOM,EQ).

Если хотя бы одно из этих двух условий нарушается, то функция называется специальной (напр. QUOTE - не выполняет действий над аргументом).

В общем случае, функции класса FSUBR отличаются от обычных встроенных функций еще и тем, что число аргументов для них может быть произвольным (напр. COND).

Для связи имени функции, определяемой программистом, с определяющим выражением в Лиспе используются функции: DEFUN (DF,DFUN,PUTD).

Функция, связывающая имя функции с определяещим выражением имеет формат

(DEFUN fun

(LAMBDA (X1 ... Xn) e)),

где fun - имя функции;

(LAMBDA...)- определяющее выражение;

После такого описания можно обращаться к этой функции, используя ее имя.

Пример:

(DEFUN NATOM (LAMBDA (X)

(COND ((ATOM X) NIL) (T T) )

)

)

Обращение к функции:

(NATOM 'A)->NIL

DEFUN – определяет тип EXPT

LAMBDA - определяет тип FEXPR.

можно упростить запись определения функции NATOM, опуская выражение LAMBDA с его скобками:

(DEFUN NATOM

(COND ((ATOM X) NIL) (T T) )

)

В muLisp общей формат DEFUM можно определить следующим образом:

(DEFUN fun (арг)

задача 1

 записи на языке

задача 2

)

Задачи, приведенные в определении, бывают простыми и условными. Простая задача в качестве 1-го элемента списка содержит атом. В условной задаче на 1-м месте стоит предикат и ее формат (р е). Если предикат р истинен, то вычисляется значение е и вычисленное значение является значением определяемой функции. Если р – ложь, то выполняется переход к следующей задаче.

Определим функцию, объединяющую два элемента в список:

(DEFUM LIST1 (U V)

(CONS U (CONS V NIL))

)

- простая задача (CONS – атом)

Обращение к функции:

(LIST1 ‘(A B) ‘(C D)) ((A B)(C D))

(список из двух подсписков)

(LIST1 (CAR '(P Q R))(CDR '(PP QQ RR)) ) (P (QQ RR))

Определение функции “не атом” на языке muLisp

(DEFUN NATOM

((NULL (ATOM X)) T)

)

можно записать еще короче, опустив в записи (р е) е и значением, будет значение р:

(DEFUN NATOM

(NULL (ATOM X))

)

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