Основы программирования в Лиспе. Функции. Рекурсия Лекция 11.

Презентация:



Advertisements
Похожие презентации
Функционалы. Методы обработки S-выражений. Методы обработки списков Лекция 12.
Advertisements

ИМЯ И ЗНАЧЕНИЕ СИМВОЛА Функциональное программирование Григорьева И.В.
ДРУГИЕ ФОРМЫ РЕКУРСИИ I Функциональноепрограммирование Григорьева И.В.
Определение функций Функциональное программирование Григорьева И.В.
Базовые функции Функциональное программирование Григорьева И.В.
ФУНКЦИИ БОЛЕЕ ВЫСОКОГО ПОРЯДКА Функциональное программирование Григорьева И.В.
ВНУТРЕННЕЕ ПРЕДСТАВЛЕНИЕ СПИСКОВ. Лисповская память состоит из списочных ячеек Лисповская память состоит из списочных ячеек Значение представляется указателем.
Функциональное программирование МарГТУ2009 г. 1 Функции. Базовые функции. Лекция 2.
Другие формы рекурсии II Функциональное программирование Григорьева И.В.
ПЕРЕДАЧА ПАРАМЕТРОВ И ОБЛАСТЬ ИХ ДЕЙСТВИЯ Функциональное программирование Григорьева И.В.
Переменная - это величина, которая имеет имя, тип и значение. Значение переменной может меняться во время выполнения программы. В компьютерах каждая переменная.
ВЫЧИСЛЕНИЕ В ЛИСПЕ Функциональное программирование Григорьева И.В.
Объектно-ориентированный язык программирования. Переменная - эта поименованная ячейка памяти, хранящая какое-либо одно значение (одно число, один фрагмент.
1 Кубенский А.А. Функциональное программирование. Глава 3. Стили функционального программирования. Глава 3. Стили функционального программирования 3.1.
1 Кубенский А.А. Функциональное программирование. Глава 4. Основы лямбда-исчисления Рекурсия в лямбда-исчислении fac = λn.(if (= n 0) 1 (* n (fac.
Программирование при помощи отображений Функциональные отношения и базовые функции Lisp Функции Eugeny L Yakimovitch 2008
Языки и методы программирования Преподаватель – доцент каф. ИТиМПИ Кузнецова Е.М. Лекция 5.
Лекция 4 Программирование на Паскале. Элементы языка Турбо Паскаль 7.0. Типы данных. Управляющие конструкции.
Функциональное программирование Язык Lisp. Введение.
Функциональное программирование Лекция 2 (13) Функционалы и их разновидности.
Транксрипт:

Основы программирования в Лиспе. Функции. Рекурсия Лекция 11

Атомы Атом - это произвольная строка алфавитных символов, за исключением: отдельно стоящей точки отдельно стоящей левой или правой скобок или групп левых или правых скобок (за исключением открывающей и закрывающей скобки, стоящих подряд) отдельно стоящего пробела или группы пробелов отдельно стоящего апострофа или двойной кавычки

Атом Abc Это обычный атом 1Abc Это - тоже атом (хотя имя и начинается с цифры) Q$WЭто - тоже атом (хотя имя и содержит знак доллара) 123Это атом - число -12.3Это атом - число 6.02E+23Это атом - число A.AЭто атом A Это - не атом. Пробел в имени недопустим A(Это - не атом. Скобки в имени недопустимы A'BЭто - не атом. Апостроф в имени недопустим ()Это - атом. "Проба пера"Это - атом-строка. Внутри строки пробелы вполне допустимы "Проба "пера""Это - не атом. Кавычки, стоящие внутри строки, при записи должны удваиваться "Проба ""пера"""Это - атом. "Проба 'пера'"Это - атом. Апостроф внутри строки - обычный символ. &HFFFFFFЭто - атом-битовая шкала &H Это - просто атом (но не битовая шкала)

Точечные пары Точечная пара - это конструкция следующего вида: левая скобка, ноль или более пробелов, атом или точечная пара, один или более пробелов, точка, один или более пробелов, атом или точечная пара, ноль или более пробелов, правая скобка. Другими словами, точечную пару можно представить следующим образом (Нечто. Нечто) Здесь Нечто - это атом или точечная пара. Атом или точечная пара называются S-выражением.

Точечная пара (a. b)точечная пара ((1. 2). b)точечная пара ((1. 2). (3. 4))точечная пара (x. (y. z))точечная пара (1.) Не точечная пара. После точки до скобки должен стоять атом или точечная пара (. 2) Не точечная пара. После скобки до точки должен стоять атом или точечная пара (1. 2 Не точечная пара. Скобки должны быть сбалансированы (name. "Анатолий")точечная пара (A. B. C) Не точечная пара. Запись не имеет смысла

Списки Правила упрощения точечной пары: 1.Цепочки. Nil просто удаляем 2.Цепочки. ( удаляем вместе с соответствующей закрывающей скобкой. Список - это такая точечная пара, в записи которой после применения правил упрощения не остается точек.

Основные правила Регистр в именах атомах не различается (CAR, Car и car – одно и то же) Quote или – запрет на вычисление, один аргумент Математические операции: + - * \ целочисленное деление % целочисленный остаток / вещественное деление ^ >, >=,

Присваивание значений атомам Функции set, setq, csetq Set – два аргумента (атом + произвольное S-выражение) (set a 1) – ошибка, попытка вычисления атома а (set a 1) – 1 Setq – отличается от set тем, что не вычисляет значение первого аргумента (он сразу квотирован) (setq z 9) – 9 Csetq – отличается от setq тем, что значение целевого атома после успешного применения превращается в константу (csetq x 8) – х-константа, имеет значение 8 (csetq z 7) – ошибка, попытка превратить переменную в константу (setq x 6) – ошибка, попытка превратить константу в переменную

Функции CAR и CDR (CAR (1 2 3))1 (CDR (1 2 3))(2 3) (CDR (CDR '(1 2 3)))(3) (CDR (CDR (CDR '(1 2 3))))NIL (CAR '(a. b))a (CDR '(a. b))b (CAR 1)Ошибка, т.к. аргумент – атом (CDR 6)Ошибка, т.к. аргумент – атом (CDAR '((1 2) (3 4)))(2) (CAAR '((1 2) (3 4)))1 (CADR '((1 2) (3 4)))(3 4) (CDDR '((1 2) (3 4)))Nil (CDDDR '( ))(4) (CADAR '((1 2) (3 4) (5 6)))2 (CADDR '((1 2) (3 4) (5 6)))(5 6) (CADDDR '( ))4

Функции CONS и LIST Функция CONS объединяет значения двух своих аргументов в точечную пару. Если значением первого аргумента является атом, а второго - список, то результатом будет список, голова которого есть значение первого аргумента, а хвост - значение второго. Распространенной ошибкой начинающих является ожидание, что результатом вызова (CONS 'a 'b) будет список (a b). На самом деле результатом будет точечная пара (a. b). Чтобы в результате вызова получился список, нужно вызвать функцию CONS так: (CONS 'a '(b)). Вызов (CONS 'a Nil) вернет точечную пару (a. Nil), что есть список из одного элемента (a).

Функции CONS и LIST Функция LIST принимает произвольное число аргументов. Функция возвращает список, состоящий из значений аргументов. На первый взгляд, функция LIST бесполезна, ведь чтобы построить список из чисел 1, 2 и 3 достаточно написать '(1 2 3) или (QUOTE (1 2 3)). Однако, если созданы переменные z1, z2 и z3 со значениями 1, 2 и 3, то вызов '(z1 z2 z3) вернет результат (z1 z2 z3) (не произойдет замены атомов значениями). А вот вызов (LIST z1 z2 z3) вернет результат (1 2 3). Функция позволяет "собирать" из составных частей списки произвольной длины. Если какой-либо из аргументов этой функции не требуется вычислять, его можно квотировать.

Функции CONS и LIST (cons 'a 'b)(a. b) (cons 'a '(b))(a b) (cons 'a Nil)(a) (cons '(a b) '(c d))((a b) c d) (setq z1 1) (setq z2 2) (setq z3 3) '(1 2 3) (list 1 2 3) '(z1 z2 z3) (list z1 z2 z3) (1 2 3) (z1 z2 z3) (1 2 3)

Функции ATOM, EQ, NEQ, NULL, NOT Функция ATOM проверяет, является ли S- выражение атомом или нет Функция EQ сравнивает только атомы Эквивалентные записи: (eq a b) и (= a b) NB! Для сравнения S-выражений (списков) используется функция EQUAL Функция NEQ сравнивает только атомы Эквивалентные записи: (neq a b) и (<> a b) Функции NULL и NOT эквивалентны

Функции ATOM, EQ, NEQ, NULL, NOT (atom 1)T (atom '(1 2 3))NIL (atom (car '(1 2 3)))T (atom (cdr '(1 2 3)))NIL (eq 'a 'b)NIL (eq 'a 'a)T (eq '(a b) '(a b))NIL (eq Nil Nil)T (eq T T)T (neq 'a 'b)T (neq 'a 'a)NIL (eq '(a b) '(a b))T (neq Nil Nil)NIL (neq T T)NIL (not T)NIL (not Nil)T (Null Nil)T (Null 'a)NIL (Null '(1 2 3))NIL (Not nil)T

Функция COND Функция принимает произвольное количество аргументов. Каждый аргумент функции COND должен быть списком из двух элементов. Первый - условие, а второй - результат. (COND (Условие 1 Результат 1 ) (Условие 2 Результат 2 )... (Условие n Результат n )) Каждая из конструкций Условие и Результат могут быть произвольными S- выражениями (обычно - списками или атомами). Этапы вычисления: Вычисляется значение выражения Условие 1; Если это значение есть атом T, то вычисляется значение выражения Результат 1 и это значение возвращается в качестве результата функции СOND; Если это значение НЕ есть атом T, то вычисляется значение выражения Условие 2; Если это значение есть атом T, то вычисляется значение выражения Результат 2 и это значение возвращается в качестве результата функции COND; Процесс повторяется до тех пор, пока список аргументов будет исчерпан, либо пока значение одного из условий не окажется атомом T.

Функция COND (setq z1 1) (cond ((atom z1) "z1 - атом") (T "z1 - не атом")) 1 "z1 - атом" (setq z1 '(1 2)) (cond ((atom z1) "z1 - атом") (T "z1 - не атом")) (1 2) "z1 - не атом"

Универсальная функция EVAL Функция EVAL вычисляет значение своего единственного аргумента и возвращает его в качестве результата. Функцию EVAL можно употреблять при необходимости вычислить значение S-выражения, построенного динамически (в процессе вычислений). Другое применение функции EVAL состоит в вычислении значений аргументов функции в теле самой функции. Функция EVAL противоположна по своему действию функции QUOTE - для любого S-выражения x результат вызова (EVAL (QUOTE x)) совпадает с x.

Создание собственных функций - функция DEFUN (DEFUN имя_функции (список_параметров) (тело_функции)) Пример – разность квадратов аргументов: Функция: (DEFUN QDIF (x y) (* (- x y) (+ x y))) Вызов: (QDIF 7 8) Возврат: -15 Вызов: (QDIF 7 8) Возврат: 15 Вызов: (QDIF ) Возврат: ошибка Вызов: (QDIF 7 8 9) Возврат: ошибка

Функция DEFUN Важный принцип Лиспа: после возврата из функции значения связанных в теле функции переменных будут теми же самыми, что и до вызова функции. Если функция изменит значение свободной переменной (с помощью SET/SETQ), то это изменение останется и после выхода из функции

Функция DEFUN (DEFUN QDIF (x y) (* (- x y) (+ x y))) (setq x 6)6 (setq y 8)6 (QDIF 12 11)23 x6 y 6 (DEFUN QDIF (x y) (setq z (* (- x y) (+ x y)))) (setq z 0)0 (QDIF 5 3)16 z16

Рекурсия Пусть имеется произвольный список, состоящий из чисел. Длина списка заранее не известна. Нужно подсчитать сумму чисел, входящих в список. Если входной список пуст, то функция должна возвращать нуль. Если входной список не пуст, то сумма элементов списка равна его первому элементу (CAR) плюс сумма элементов остатка (CDR). (DEFUN SUMLIST (x) (COND ((NULL x) 0) (T (+ (CAR x) (SUMLIST (CDR x)))))) Такой код работает только для одноуровневый списков (sumlist '( )) Возврат: 15

Рекурсия (DEFUN SUMLIST (x) (COND ((NULL x) 0) (T (+ (SUMLIST (CAR x)) (SUMLIST (CDR x)))))) Первый аргумент будет атомом, а не списком, поэтому производит ошибка при вычислении CDR (DEFUN SUMLIST (x) (COND ((NULL x) 0) ((ATOM x) x) (T (+ SUMLIST (CAR x)) (SUMLIST (CDR x)))))) (sumlist '( 1 (2 3 (4)) 5)) Возврат: 15

Рекурсия Пусть заданы два произвольных списка. Требуется их объединить Например, из списков (a b c) и (d e f) получить список (a b c d e f). Результатом (CONS '(a b c) '(d e f)) будет список ((a b c) d e f), а не (a b c d e f). Составим функцию APPEND, которая будет принимать два параметра – списка. Если первый список пуст (равен Nil), то результат равен второму списку. Если первый список не пуст, то результат должен быть равен голове первого списка, присоединенной посредством функции CONS к значению функции APPEND, с хвостом первого списка (первый параметр) и исходным вторым списком (второй параметр). (DEFUN APPEND (x y) (COND ((NULL x) y) (T (CONS (CAR x) (APPEND (CDR x) y)))))

Безымянная функция - конструкция LAMBDA Суть безымянной функции состоит в том, что задается алгоритм вычисления, но не задается имя функции. (LAMBDA (список параметров) (тело функции)) Список параметров - это одноуровневый атомный список (т.е. список, состоящий только из атомов). Тело функции - это S-выражение, зависящее от атомов, входящих в список параметров. Чтобы вычислить значение безымянной функции, нужно составить S- выражение, представляющее собой список, головой которого является вся LAМBDA-конструкция, а последующими элементами - фактические параметры. Пример: ( (LAMBDA (x y) (+ (* x x) (* y y) ) ) 3 4 )

Если присвоить какому-либо атому в качестве значения корректное LAMBDA- выражение, то появляется возможность использовать это LAMBDA-выражение без повторного задания (setq sq '(LAMBDA (x y) (+ (* x x) (* y y) ))) (sq 6 7) Возврат: 85

Функциональные символы Дан произвольный список чисел, требуется построить список квадратов этих чисел: defun p2 (x) (cond ((null x) nil) (T (cons (^ (car x) 2) (p2 (cdr x)))))) Дан произвольный список чисел, требуется построить список кубов этих чисел: (defun p3 (x) (cond ((null x) nil) (T (cons (^ (car x) 3) (p3 (cdr x)))))) Опишем общую функцию: (defun pf (x f) (cond ((null x) nil) (T (cons (f (car x)) (pf (cdr x) f))))) Опишем функции для возведения в квадрат и в куб (defun f^2 (x) (^ x 2)) (defun f^3 (x) (^ x 3)) Вызов: (pf '( ) 'f^2) (pf '( ) (function f^2))