Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
У символа могут быть свойстваСодержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
В Лиспе с символом можно связать именованные свойства (property). Свойства символа записываются в хранимый вместе с символом список свойств (property list, p-list).
У свойств есть имя и значение Список свойств может быть пуст или содержать произвольное количество свойств. Его форма такова:
(имя1 значение1 имя2 значение2 … имяN значениеN) Например, у символа ЯГОДА-РЯБИНЫ может быть такой список свойств:
(вкус кислый цвет красный) Список свойств символа можно использовать без особых ограничений, его можно по необходимости обновлять или удалять. Программист должен сам предусматривать и обрабатывать интересующие его свойства.
Системные и определяемые свойства Ранее мы показали, что с символом связаны лишь его имя - произвольное, назначенное функцией присваивания (SETQ), значение; назначенное определением функции (DEFUN) описание вычислений (лямбда-выражение). Значение и определение функции являются встроенными системными свойствами, которые управляют работой интерпретатора в различных ситуациях. Функции, используемые для чтения и изменения этих свойств (SETQ, SYMBOL-VALUE, DEFUN, FUNCTION-VALUE и другие), мы уже рассматривали ранее. Весь список свойств также является системным свойством. Работающие со свойствами символов прикладные системы могут свободно определять новые свойства. Далее мы рассмотрим псевдофункции для чтения, изменения и удаления свойств, определяемых пользователем.
Чтение свойства Выяснить значение свойства, связанного с символом, можно с помощью функции GET:
(GET символ свойства) Если, например, с символом ЯГОДА-РЯБИНЫ связан определенный нами ранее список свойств, то мы получим следующие результаты:
_(get ’ягода-рябины ’вкус) КИСЛЫЙ _(get ’ягода-рябины ’вес) NIL Так как у символа ЯГОДА-РЯБИНЫ нет свойства ВЕС, то GET вернет значение NIL.
Присваивание свойства Присваивание нового свойства или изменение значения существующего свойства в основных диалектах языка Лисп осуществляется псевдофункцией PUTPROP (put property) или PUT:
(PUTPROP символ свойство значение) В Коммон Лиспе функции PUTPROP не существует. Свойства символов находятся в связанных с символами ячейках памяти, для присваивания значений которым используется обобщенная функция присваивания SETF. Присваивание свойства в Коммон Лиспе осуществляется через функции SETF и GET следующим образом:
(SETF (GET символ свойство) значение) Здесь вызов GET возвращает в качестве значения ячейку памяти для данного свойства, содержимое которой обновляет вызов SETF. Присваивание будет работать и в том случае, если ранее у символа не было такого свойства. Приведем пример:
_(setf (get ’ягода-рябины ’вес) ’(2 g)) (2 G) _(get ’ягода-рябины ’вес) (2 G) Побочным эффектом вызова будет изменение списка свойств символа ЯГОДА-РЯБИНЫ следующим образом:
(ВЕС (2 G) ВКУС КИСЛЫЙ ЦВЕТ КРАСНЫЙ) Псевдофункция SETF меняет физическую структуру списка свойств. Поэтому использование других списков как части списка свойств без их предварительного копирования может привести к неожиданным ошибкам.
Удаление свойства Удаление свойства и его значения осуществляется псевдофункцией REMPROP:
(REMPROP символ свойство) Приведем пример:
_(remprop ’ягода-рябины ’вкус) ВКУС _(get ’ягода-рябины ’вкус) NIL Псевдофункция REMPROP возвращает в качестве значения имя удаляемого свойства. Если удаляемого свойства нет, то возвращается NIL. Свойство можно удалить, присвоив ему значение NIL. В этом случае имя свойства и значение NIL физически остаются в списке свойств. Читать из списка свойств, создавать и обновлять в нем свойства можно не только по отдельности, но и целиком. Например, в Коммон Лиспе значением вызова
(SYMBOL-PLIST символ) является весь список свойств:
_(symbol-plist ’ягода-рябины) (ВЕС (2 G) ЦВЕТ КРАСНЫЙ) Свойства глобальны Свойства символов независимо от их значений доступны из всех контекстов до тех пор, пока они не будут явно изменены или удалены. Использование символа в качестве функции или переменной, т.е. изменение значения символа или определения функции, не влияет на другие свойства символа, и они сохраняются. Список свойств используется во многих системных программах Лисп-систем. Наличие свойств полезно как для поддержки работы самой Лисп-системы, так и во многих типичных случаях представления данных. Использование свойств дает средства для программирования, управляемого данными, с помощью которого можно реализовать различные языки представления знаний и формализмы, такие как семантические сети, фреймы и объекты объектно-ориентированного программирования. В некоторых системах можно использовать в качестве обобщения так называемые свободные списки свойств (disembodied property list), несвязанные с каким-либо символом.
ЛАБОРАТОРНАЯ РАБОТА №9
1. Будут ли меняться списки свойств статических и динамических переменных при смене контекста? Если да, то как?
2. Предположим, что у имени города есть свойства х и y, которые содержат координаты места нахождения города относительно некоторого начала координат. Напишите функцию (РАССТОЯНИЕ a b), вычисляющую расстояние между городами a и b, если значением функции (SQRT x) является квадратный корень числа х.
3. Предположим, что отец и мать некоторого лица, хранятся как значения соответствующих свойств у символа, обозначающего это лицо. Напишите функцию (РОДИТЕЛИ х), которая возвращает в качестве значения родителей, и предикат (СЕСТРЫ-БРАТЬЯ х1 х2), который истинен в случае, если х1 и х2 – сестры или братья, родные или с одним общим родителем.
4. Определите функцию REMPROPS, которая удаляет все свойства символа.
5. Функция GET возвращает в качестве результата NIL в том случае, если у символа нет данного свойства, либо если значением этого свойства является NIL. Следовательно, функцией GET нельзя проверить, есть ли некоторое свойство в вписке свойств. Напишите предикат
(HASPROP символ свойство)
который проверяет, обладает ли символ данным свойством.
ВВОД И ВЫВОД
Ввод и вывод входят в диалог До сих пор в определенных нами функциях ввод данных (READ) и вывод (PRINT) осуществлялись в процессе диалога с интерпретатором. Интерпретатор читал вводимое пользователем выражение, вычислял его значение и возвращал его пользователю. Сами формы и функции не содержали ничего, связанного с вводом или выводом. Если не использовать специальную команду ввода, то данные можно передавать лисповской функции только через параметры и свободные переменные. Соответственно, без использования вывода, результат можно получить лишь через конечное значение выражения. Часто все же возникает необходимость вводить исходные данные и выдавать сообщения и тем самым управлять и получать промежуточные результаты во время вычислений, как это делается и в других языках программирования. Далее мы рассмотрим чтение и выдачу результатов, осуществляемые между Лисп-системой и пользователем. Эти функции, как будет видно далее, подходят и для управления файлами.
READ читает и возвращает выражение Как только интерпретатор встречает предложение READ, вычисления приостанавливаются до тех пор, пока пользователь не введет какой-нибудь символ или целиком выражение:
_(read) (вводимое выражение); выражение пользователя (ВВОДИМОЕ ВЫРАЖЕНИЕ); значение функции READ Обратите внимание, READ никак не показывает, что он ждет ввода выражения. Программист должен сам сообщить об этом при помощи рассматриваемых позже функций вывода. READ лишь читает выражение и возвращает в качестве значения само это выражение, после чего вычисления продолжаются. У приведенного выше вызова функции READ не было аргументов, но у этой функции есть значение, которое совпадает с введенным выражением. По своему действию READ представляет собой функцию, но у нее есть побочный эффект, состоящий именно во вводе выражения. Учитывая это, READ является не чистой функцией, в псевдофункцией. Если прочитанное значение необходимо сохранить для дальнейшего использования, то вызов READ должен быть аргументом какой-нибудь формы, например присваивания (SETQ), которая свяжет полученное выражение:
_(setq input (read)) (+ 2 3); введенное выражение (+ 2 3); значение _(input) (+ 2 3) Форма, вызывающая интерпретатор, и функция READ совместно с другими функциями позволяют читать выражения внешние по отношению к программе. Из них можно строить новые лисповские выражения или целые программы. Построенные структуры можно вычислить, передав их непосредственно интерпретатору:
_(eval input) _(eval (list (read) (read) (read))) (+ 2 3)
|
||||
Последнее изменение этой страницы: 2016-09-05; просмотров: 682; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.188.219.131 (0.009 с.) |