Главная » Все файлы » Просмотр файлов из архивов » PDF-файлы » Е.И. Большакова, Н.В. Груздева - Основы программирования на языке Лисп

Е.И. Большакова, Н.В. Груздева - Основы программирования на языке Лисп, страница 5

PDF-файл Е.И. Большакова, Н.В. Груздева - Основы программирования на языке Лисп, страница 5 Искусственный интеллект (53445): Книга - 7 семестрЕ.И. Большакова, Н.В. Груздева - Основы программирования на языке Лисп: Искусственный интеллект - PDF, страница 5 (53445) - СтудИзба2019-09-18СтудИзба

Описание файла

PDF-файл из архива "Е.И. Большакова, Н.В. Груздева - Основы программирования на языке Лисп", который расположен в категории "". Всё это находится в предмете "искусственный интеллект" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Просмотр PDF-файла онлайн

Текст 5 страницы из PDF

количество элементов на верхнем уровне:(Length '(A (5 6) D)) => 3.22Ясно, что для этого необходимо организовать проход по верхнемууровню списка-аргумента с одновременным подсчётом числа егоэлементов. Из функций базового набора для реализации прохода подходятлишь функции car и cdr.

В рассматриваемой задаче достаточноиспользовать функцию cdr, вырабатывающую хвост списка – еёпоследовательное применение и будет означать движение по верхнемууровню списка. Ясно, что применять cdr следует до тех пор, пока списокне закончится, т.е. не станет пустым. Для подсчета длины будемиспользовать следующее правило: длина списка равна длине его хвоста,увеличенной на 1. Очевидно, что длина пустого списка равна нулю.

Такимобразом, получаем функцию, телом которой служит условное выражение сдвумя ветвями:(defun Length (L)(cond ((null L) 0)(T (+ 1 (Length (cdr L))) )))Вторая ветвь функции содержит рекурсивный вызов, а первая –условие выхода из рекурсии (равенство аргумента функции пустомусписку). Ветви рекурсивной функции, не содержащие рекурсивныхвызовов и определяющие условия завершения рекурсии, называютсяэлементарными. Обычно элементарные ветви предшествуют ветвям срекурсивными вызовами.В данном решении задачи рекурсивные вычисления обязательнозакончатся, поскольку с каждым рекурсивным вызовом функции Lengthсписок-аргумент становится на один элемент короче, и по исчерпанииэлементов списка проработает первая, элементарная ветвь функции.Для понимания хода вычисления рекурсивной функции полезнотрассировать её вычисление для конкретных значений аргументов. Лиспинтерпретатор для выполнения рекурсивных вызовов использует стек, вкотором запоминаются ещё необработанные вызовы (отложенныевычисления).

Ниже схематично показано изменение содержимого стека входе вычисления вызова Length с аргументом (А (5 6) D):(Length: L=(A (5 6) D) )=> 3→ (+ 1 (Length: L=((5 6) D) ))=> 3 ↑→ (+ 1 (Length: L=(D) ))=> 2 ↑→ (+ 1 (Length: L=() ) ) => 1 ↑└────=>0────┘Первоначально в стеке находится исходное обращение к функцииLength, с помощью знака = указано значение её формального параметраL. Затем в стек поочередно заносятся функциональные вызовы,получаемые в результате работы второй ветви функции Length.

Каждое23записываемое в стек выражение – это вызов функции сложения саргументом-вызовом Length при новом значении её параметра L. Внашем изображении стека эти вызовы записываются на очередной строке,и стоящая слева от них стрелка → означает занесение их в стек. Дляформального параметра L в каждом вызове Length указывается еголокальное значение.Стек растёт до тех пор, пока в него не попадёт выражение,содержащее вызов Length с аргументом, равным NIL. Это выражениеможно сразу вычислить (проработает элементарная ветвь функции,вычисляющая длину пустого списка) и убрать его из стека. Вычисленноезначение используется для вычисления предыдущего записанного в стеквыражения.

Так последовательно, в обратном порядке выполняютсяотложенные в стек функциональные вызовы, и вычисленные при этомзначения передаются для вычисления других отложенных в стеквыражений. В нашем схематическом изображении эта передачапоказывается стрелкой ↑, стоящей справа от вычисленных значений. Этотпроцесс заканчивается, когда стек пуст и вычислено значение исходногообращения к функции Length.Отметим, что при заполнении стека новые локальные связипеременной-параметра L отменяют на время старые, но старые связивосстанавливаются лисп-интерпретатором тогда, когда вычислениявозвращаются к соответствующему функциональному вызову.В качестве следующей задачи запрограммируем функцию-предикатMember от двух аргументов А и L: (Member А L).

Функция проверяет,входит ли аргумент-атом А в заданный список L на верхнем его уровне, ивырабатывает по результатам этой проверки значение T или NIL:(Member 'Q '(Е (C) Q В)) => T(Member 'Q '(Е (C) В)) => NILОба аргумента функции вычисляются. Будем предполагать, что значениеаргумента А всегда есть символьный атом, в то же время список L можетсодержать на верхнем уровне неатомарные элементы.Как и в предыдущей задаче, требуется последовательный просмотрсписка, однако теперь необходимо ещё сравнение очередного элементасписка с заданным атомом. Проход по списку опять можно организовать спомощью функции cdr, тогда очередной элемент списка может бытьполучен обращением к функции car.

Сравнение этого элемента созначением аргумента А реализует функция eq (она требует обязательнойатомарности только одного своего аргумента). Поскольку возможны дваразных исхода сравнения, необходимы две ветви функции: если найденатом A, то следует завершить вычисление функции со значением T, если24же результат сравнения отрицателен, то необходимо рекурсивнопродолжать поиск атома А (в хвосте списка L). Если же в процессерекурсивных вызовов список L стал пуст, это означает, что искомого атоманет в этом списке, и значение функции должно быть равно NIL.Получающееся таким образом определение функции:(defun Member (А L)(cond ((null L) NIL)((eq A (car L)) T)(T (Member A (cdr L)) )))Эта функция имеет три ветви, из них две первые – элементарные,порядок всех ветвей строго определён.

Первая ветвь работает в том случае,когда список L пуст, и не может быть переставлена со второй, так какфункция car должна иметь непустой аргумент-список. Завершаемостьрекурсивных вычислений гарантируется тем, что рекурсивный вызовпроисходит с более простым аргументом.Схематично покажем процесс рекурсивных вычислений в стеке:(Member: A=Q, L=(Е (C) Q B) )=> T→ (Member: A=Q, L=((C) Q B) )=> T ↑→ (Member: A=Q, L=(Q B)) => T ↑Заметим, что во многих реализациях Лиспа (в том числе в MuLisp иCommonLisp) есть встроенная функция member, отличающаяся отзапрограммированной нами тем, что если атом-значение параметра Австречается в списке L, то функция в качестве своего значения выдаётчасть списка, начинающуюся с этого атома:(member 'Q '(Е (C) Q В)) => (Q В) .Такая особенность позволяет использовать member и как предикат, и какфункцию поиска нужного подсписка.

Для её реализации во второй ветвиприведённого выше определения функции надо заменить атом T напеременную L.Ещё одна задача – построение рекурсивной функции Append отдвух аргументов-списков L1 и L2. Функция соединяет (сливает)элементы верхнего уровня обоих списков в один список, например:(Append '(Q R T) '(K M)) => (Q R T K M)(Append '(B (A)) '((C C) () D))=> (B (A) (C C) NIL D)Действие Append иногда называют конкатенацией списков. Врезультате должен быть построен новый список, на верхнем уровнекоторого находятся сначала элементы верхнего уровня первого списка, а25затем – элементы верхнего уровня второго списка, причём в той жепоследовательности, что и в исходных списках. Поскольку в базовомнаборе функций Лиспа есть только одна встроенная функция cons,формирующая новый список, то для решения нашей задачи придётсяпоследовательно её использовать, каждый раз отщепляя очереднойэлемент от одного из списков-аргументов (например, от первого) иприсоединяя его к другому при помощи cons.

Этот процесс надозакончить, когда первый список-аргумент станет пустым (при этомзначением функции будет второй список).Определённая таким образом функция имеет две ветви:(defun Append(L1 L2)(cond ((null L1) L2)(T (cons (car L1)(Append (cdr L1) L2)))))Ключевым при программировании рекурсивной ветви являетсяправильный порядок вызовов функций, согласно следующей идее:результат слияния двух списков есть результат присоединения первогоэлемента первого списка-аргумента к списку, получающемуся в результатерекурсивного слияния хвоста первого списка со вторым списком.Рассмотрим вычисление вызова функции Append в стеке:(Append: L1=(Q R T), L2= (K M) )=> (Q R T K M)→(cons 'Q(Append: L1=(R T), L2=(K M)))=>(Q R T K M)↑→(cons 'R(Append: L1=(T), L2=(K M) )) =>(R T K M)↑→(cons 'T(Append: L1=(),L2=(K M))) =>(T K M)↑└───────=>(K M)─────┘Видно, что реальное присоединение элементов первого списка ко второмусписку откладывается до тех пор, пока не проработает элементарная ветвьфункции.

Тогда будет вычислено выражение, положенное в стекпоследним (в нём подчеркнуто вычисленное по элементарной ветвиобращение к Append и показано полученное значение), и начнётсяпоочередное вычисление предыдущих отложенных функциональныхвызовов. Результирующий список (Q R T K M) последовательностроится, начиная с присоединения T (последнего элемента первогосписка-аргумента) к началу второго списка.Если же поменять в рекурсивной ветви определения функцииAppend порядок вызовов функций cons и Append, то получим функциюRevAppend:26(defun RevAppend(L1 L2)(cond ((null L1) L2)(T (RevAppend (cdr L1)(cons (car L1) L2)) )))Эта функция при соединении списков будет менять порядокследования элементов первого списка на противоположный:(RevAppend '(Q R T) '(K M)) => (T R Q K M) .В этом можно убедиться, проследив вычисление функции в стеке:(RevAppend: L1=(Q R T), L2= (K M))=> (T→(RevAppend: L1=(R T), L2=(Q K M)) => (T→(RevAppend: L1=(T), L2=(R Q K M)) => (T→(RevAppend: L1=(), L2=(T R Q K M))=>(TRRRRQQQQKKKKM)M)↑M)↑M)↑Рассмотренная функция Аppend является встроенной в диалектахCommon Lisp и MuLisp.1.6.

S-выраженияОсновной лисповской структурой данных является так называемоеS-выражение, обобщающее понятие списка и атома:S-выражение ::= атом | (S-выражение └─┘.└─┘S-выражение)Как и ранее, знак └─┘ в приведённой БНФ обозначает пробел.В простейшем случае лисповское выражение – это атом, а в болеесложном – списочная структура, или точечная пара, соединяющая дваS-выражения. Как и введённое ранее понятие лисповского списка, понятиеS-выражения определяется рекурсивно и допускает произвольноеколичество вложений точечных пар друг в друга, например:((Т . К) . NIL)((А . В) .(С . (А .

Е )))В общем случае разделяющая точка в точечной паре должна бытьвыделена пробелами слева и справа, чтобы не слиться со стоящим слеваили справа атомом (т.к. обычно точка допускается в именах атомов). Еслиже слева или справа от точки стоит скобка, то соответствующий пробелможет быть опущен.Для S-выражений функции базового набора car, cdr и consопределены следующим образом.

Пусть значением формы Е являетсяS-выражение (v1 . v2), а v1 и v2 – некоторые S-выражения:Е => (v1 . v2) ,тогда(car Е) => v1 , (cdr Е) => v2 .27Если S-выражения e1 и e2 имеют значения v1 и v2 соответственно:e1 => v1 ,e2 => v2 ,то(cons e1 e2) => (v1 . v2) .Таким образом, аргументами функции cons могут быть произвольныелисповские выражения, в том числе – атомы.Поскольку S-выражение – обобщение понятий атома и списка, вселисповские списки можно записать как S-выражения, используя точечнуюзапись.

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Нашёл ошибку?
Или хочешь предложить что-то улучшить на этой странице? Напиши об этом и получи бонус!
Бонус рассчитывается индивидуально в каждом случае и может быть в виде баллов или бесплатной услуги от студизбы.
Предложить исправление
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5137
Авторов
на СтудИзбе
441
Средний доход
с одного платного файла
Обучение Подробнее