Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
EQL сравнивает числа одинаковых типовСодержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Более общим, по сравнению с EQ, является предикат EQL, который работает так же, как EQ, но дополнительно позволяет сравнивать однотипные числа (и элементы строк).
_(eql 3 3); сравниваются два целых числа T _(eql 3.0 3.0); сравниваются два вещественных числа T _(eql 3 3.0); не годится для разных типов NIL Предикат EQL, как правило, используется во многих встроенных функциях, осуществляющих более сложные операции сравнения. Его использование для сравнения списков – это часто встречающаяся ошибка.
Предикат = сравнивает числа различных типов Сложности, возникающие при сравнении чисел, легко преодолимы с помощью предиката =, значением которого является Т в случае равенства чисел независимо от их типов и внешнего вида записи:
_(= 3 3.0) Т _(= 3.00 0.3Е1) Т Обеспечить применение предиката к числовым аргументам может предикат NUMBERP, который истинен для чисел:
_(numberp 3e-34) T _(numberp t) NIL
EQUAL проверяет идентичность записей Обобщением EQL является предикат EQUAL. Он работает как EQL, но, кроме того, проверяет одинаковость двух списков:
_(equal ’ x ’ x) T _(equal ’ (x y z) ’ (x y z)) T _(equal ’ (a b c) (cons ’ a ’ (b c))) T _(equal ’ (nil) ’ ((nil))) NIL Принцип работы предиката EQUAL состоит в следующем: если внешняя структура двух лисповских объектов одинакова, то эти объекты между собой равны в смысле EQUAL. Предикат EQUAL также применим к числам и к другим типам данных (например, к строкам). Заметим, что в соответствии со своим принципом работы он не подходит для сравнения разнотипных чисел, так как их внешние представления различаются:
_(equal 3.00 3); различное внешнее представление NIL _(= 3.00 3) T EQUALP проверяет наиболее общее логическое равенство Наиболее общим предикатом, проверяющим в Коммон Лиспе наличие логического равенства, является EQUALP, с помощью которого можно сравнивать произвольные лисповские объекты, будь то числа различных типов, выражения или другие объекты. Этот предикат может потребоваться, когда нет уверенности в типе сравниваемых объектов или в корректности использования других предикатов сравнения. Недостатком универсальных предикатов и функций типа EQUALP является то, что их применение требует от системы несколько большего объема вычислений, чем использование специализированных предикатов и функций.
Другие примитивы Несмотря на то, что обычную обработку списков всегда можно свести к описанным ранее трем базовым функциям (CONS, CAR, CDR) и двум базовым предикатам (АТОМ и EQ), программирование лишь с их использованием было бы очень примитивным и похожим на программирование на внутреннем машинном языке. Поэтому в Лисп-систему включено множество встроенных функций для различных действий и различных ситуаций. Далее мы рассмотрим некоторые такие примитивы.
NULL проверяет на пустой список Встроенная функция NULL проверяет, является ли аргумент пустым списком:
_(null ’ ()) T _(null (cddr ’ (a b c))) NIL _(null NIL) T _(null T) NIL Из последних двух примеров видно, что NULL работает как логическое отрицание, у которого в Лиспе есть и свой, принадлежащий логическим функциям, предикат (NOT x):
_(not (null nil)) NIL Функции NULL и NOT можно выразить через EQ:
(NULL x) ó (EQ NIL x) Вложенные вызовы CAR и CDR можно записывать в сокращенном виде Комбинируя селекторы CAR и CDR, можно выделить произвольный элемент списка. Например:
_(cdr (cdr (car ’ ((a b c) (d e) (f))))) (C) Комбинации вызовов CAR и CDR образуют уходящие в глубину списка обращения, и в Лиспе используется для этого более короткая запись: желаемую комбинацию вызовов CAR и CDR можно записать в виде одного вызова функции:
(С…R список) Вместо многоточия записывается нужная комбинация из букв А (для функции CAR) и D (для функции CDR):
(cadr x) ó (car (cdr x)) (cddar x) ó (cdr (cdr (car x))) Например:
_(cadr ’ (программировать на Лиспе просто?)) НА _(caddr ’ ((a b c) (d e) (f))) (F) _(cadar (cons ’ (a b) nil)) B Для функций CAR, CADR, CADDR, CADDDR и т.д. в Коммон Лиспе используются и более наглядные имена FIRST, SECOND, THIRD и т.д. Можно воспользоваться и наиболее общей функцией NTH, выделяющей n-й элемент списка:
(NTH n список) _(nth 2 ’ (1 2 3)); индексы начинаются с нуля _(third (cons 1 (cons 2 (cons 3 nil)))) _(fourth ’ (1 2 3)) NIL Последний элемент списка можно выделить с помощью функции LAST:
(LAST x) LIST создает список из элементов Другой, часто используемой, встроенной функцией является
(LIST x1 x2 x3 …),
которая возвращает в качестве своего значения список из значений аргументов. Количество аргументов функции LIST произвольно:
_(list 1 2) (1 2) _(list ’ a ’ b (+ 1 2)) (A B 3) _(list ’a ’ (b c) ’d) (A (B C) D) _(list NIL) (NIL) Построение списков нетрудно свести к вложенным вызовам функции CONS, причем вторым аргументом последнего вызова является NIL, служащий основой для наращивания списка:
_(cons ’c NIL) (C); ó (list ’c) _(cons ’b (cons ’c NIL)); ó (list ’b ’c) (B C) _(cons ’a (cons ’b (cons ’c NIL))) (A B C)
ЛАБОРАТОРНАЯ РАБОТА №3
1. Перечислите базовые функции языка Лисп. Каковы типы их аргументов, и какие значения они возвращают в качестве результата?
2. Запишите последовательности вызовов CAR и CDR, выделяющие из приведенных ниже списков символ «цель». Упростите эти вызовы с помощью функций C…R. a) (1 2 цель 3 4) b) ((1) (2 цель) (3 (4))) c) ((1 (2 (3 4 цель))))
3. Вычислите значения следующих выражений. a) cons nil ’(суть пустой список)) b) (cons nil nil) c) (cons ’(nil) ’(nil)) d) (cons (car ’(a b)) (cdr ’(a b))) e) (car ’(car (a b c))) f) (cdr (car (cdr ’(a b c)))) g) (list (list ’a ’b) ’(car (c d)))
4. Какие из следующих вызовов возвращают значение Т? a) (atom ’(cdr nil)) b) (equal ’(a b) (cons ’(a) ’(b))) c) (atom (* 2 (+ 2 3))) d) (null (null t)) e) (eq nil (null nil)) f) (eq1 2.0 2) g) (equal 2.0 2) h) (= 2.0 2) i) (equalp 2.0 2) j) (equalp (atom nil) (caar ’((t))))
ИМЯ И ЗНАЧЕНИЕ СИМВОЛА Значением константы является сама константа Символ может обозначать произвольное выражение SET вычисляет имя и связывает его SETQ связывает имя, не вычисляя его SETF – обобщенная функция присваивания Побочный эффект псевдофункции Вызов интерпретатора EVAL вычисляет значение значения Основной цикл: READ-EVAL-PRINT
Значением константы является сама константы Так же как выражение, являющееся вызовом функции, без предшествующего апострофа представляет значение выражения, а не само выражение, так и атомы могут использоваться для обозначения каких-нибудь значений. Мы уже обращали внимание на то, что перед лисповскими константами (числами и символами Е и NIL) не надо ставить апостроф. Как константы они обозначают самих себя. Если мы введем константу, то интерпретатор в качестве результата выдаст саму эту константу:
_t T _’t T _nil NIL _3.14 3.14
Символ может обозначать произвольное выражение Символы можно использовать как переменные. В этом случае они могут обозначать некоторые выражения. У символов изначально нет какого-нибудь значения, как у констант. Если, например, введем символ ФУНКЦИИ, то мы получим сообщение об ошибке:
_функции; у символа нет значения Error: Unbound atom ФУНКЦИИ Интерпретатор здесь не может вычислить значение символа, поскольку его у него нет.
SET вычисляет имя и связывает его При помощи функции SET символу можно присвоить (set) или связать (bind) с ним некоторое значение. Если, например, мы хотим, чтобы символ ФУНКЦИИ обозначал базовые функции Лиспа, то введем:
_(set ’функции ’(car cdr cons atom eq)) (CAR CDR CONS ATOM EQ)
Теперь между символом ФУНКЦИИ и значением (CAR CDR CONS ATOM EQ) образована связь (binding), которая действительна до окончания работы, если, конечно, этому имени функцией SET не будет присвоено новое значение. После присваивания интерпретатор уже может вычислить значение символа ФУНКЦИИ:
_функции (CAR CDR CONS ATOM EQ) Обратите внимание, что SET вычисляет оба аргумента. Если перед первым аргументом нет апострофа, то с помощью функции SET можно присвоить значение имени, которое получается путем вычисления, Например, вызов
_(set (car функции) ’(взбрести в голову)) ВЗБРЕСТИ В ГОЛОВУ Присваивает переменной CAR выражение (ВЗБРЕСТИ В ГОЛОВУ), так как вызов (CAR ФУНКЦИИ) возвращает в качестве значения символ CAR, который и используется как фактический аргумент вызова функции SET:
_(car функции) CAR _CAR (ВЗБРЕСТИ В ГОЛОВУ) _функции (CAR CDR CONS ATOM EQ) На значение символа можно сослаться, записав его без апострофа. Значение имени никак не проявится до тех пор, пока оно не примет участия в вычислениях. Значения символов определяются с помощью специальной функции SYMBOL-VALUE, которая возвращает в качестве своего значения значение символа, являющегося ее аргументом.
_(symbol-value (car функции)) (ВЗБРЕСТИ В ГОЛОВУ)
|
||||
Последнее изменение этой страницы: 2016-09-05; просмотров: 419; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.143.7.53 (0.008 с.) |