Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы1_2_Лисп

.doc
Скачиваний:
15
Добавлен:
13.02.2015
Размер:
293.38 Кб
Скачать

8

Лабораторная работа № 1

Вычисление функций на Лиспе

Цель работы: изучение правил записи функциональных зависимостей в Лиспе и написание простейших программ по вычислению функций.

Краткие теоретические сведения

Функциональная программа

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

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

Чистое функциональное программирование не признает присваивания и передач управления. Разветвление вычислений основано на механизме обработки аргументов условного предложения.

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

Понятие функции и формы ее записи

Функцией в математике называется отображение, которое однозначно отображает одни знаячения на другие.

Например, в выражении

,

любому x из области определения функции ставится в соответствие единственное значение y из области допустимых значений функции.

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

В арифметических выражениях используется также инфиксная запись, где имя функции или действие располагается между аргументами: , .

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

Пример. Выражение записывается как: .

Пример. Записать выражение: sin(x-3)+7 примет вид: (+ (sin (- x 3)) 7).

Диалог с интерпретатором Лиспа

Транслятор Лиспа работает как правило в режиме интерпретатора.

Read-eval-print цикл:

loop { read

evaluate

print}

В Лиспе сразу читается , затем вычисляется (evaluate) значение функции и выдается значение.

Функция QUOTE

В некоторых случаях не требуется вычисления значений выражений, а требуются само выражение. Если прямо ввести (+ 2 3) , то 5 получится как значение. Но можно понимать (+ 2 3) не как функцию, а как список. S‑выражения, которые не надо вычислять, помечают для интерпретатора апострофом " ' " (quote).

Пример.

‘ (+ 2 3)

Ответ интерпретатора: (+ 2 3)

Пример.

(QUOTE y)

Ответ интерпретатора: y

Использование символов в качестве переменных

Изначально символы в Лиспе не имеют значения. Значения имеют только константы. Для связывания символов используются функции SET, SETQ и SETF.

Функция SET связывает символ со значением, предварительно вычисляя значения аргументов. В качестве значения SET возвращает значение второго аргумента.

Пример.

(SETd ‘(x y z))

Ответ интерпретатора: (x y z)

d

Ответ интерпретатора: (x y z)

Пример.

(SETab)

Ответ интерпретатора: b

a

Ответ интерпретатора: b

Пример. Здесь вычисляется последовательность операторов: a = 1; b = a+2.

(SETa 1)

Ответ интерпретатора: 1

(SETb (+ a 2))

Ответ интерпретатора: 3

b

Ответ интерпретатора: 3

Если перед первым аргументом нет апострофа, то значение будет присвоено значению этого аргумента.

Пример.

(set 'a 'b)

Ответ интерпретатора: b

(set a 'e)

Ответ интерпретатора: e

a

Ответ интерпретатора: b

b

Ответ интерпретатора: e

Функция SETQ аналогична SET, но не вычисляет значения первого аргумента. Буква Q в имени SETQ означает блокировку.

Пример.

(setq mk)

Ответ интерпретатора: k

m

Ответ интерпретатора: k

Пример.

(setq x 1)

Ответ интерпретатора: 1

x

Ответ интерпретатора: 1

(sin x)

Ответ интерпретатора: 0.841471

Арифметические функции

Арифметические функции могут быть использованы с целыми или действительными аргументами.

Число аргументов для большинства арифметических функций может быть разным.

(+ x1 x2 ... xn) возвращает x1 + x2 + x3 + ... + xn.

(- x1 x2 ... xn) возвращает x1 - x2 - x3 - ... - xn.

(* y1 y2 ... yn) возвращает y1 x y2 * y3 * ... * yn.

(/ x1 x2 ... xn) возвращает x1/x2/... /xn.

Задание

Вычислить на Лиспе значение заданного выражения.

Пример выполнения задания

Пусть задана зависимость: . Значение переменной x задать при помощи SET или SETQ.

Программа на Лиспе приняла вид:

(setq x 1)

Ответ интерпретатора: 1

(setq y (+ (* 5 x x x) (* (sin (* 3 x)) (sin (* 3 x))) 2))

Ответ интерпретатора: 7.01991.

Варианты заданий

1. 

6. 

2. 

7. 

3. 

8. 

4. 

9. 

5. 

10. 

11. 

20. 

12. 

21. 

13. 

22. 

14. 

23. 

15. 

24. 

16. 

25. 

17. 

26. 

18. 

27. 

19. 

28. 

Контрольные вопросы

1. Что такое функциональная программа.

2. Формы записи функции.

3. Функция QUOTE.

4. Функция SET.

5. Функция SETQ.

6. Написать программу вычисления заданной преподавателем функциональной зависимости на языке Лисп.

Лабораторная работа № 2

Написание функций пользователя на Лиспе

Цель работы: изучение правил создания и вызова пользовательских функций на Лиспе.

Краткие теоретические сведения

Определение функций

Функцию можно определить самим и использовать как встроенную. Для определения функции необходимо:

1) дать имя функции;

2) определить параметры функции;

3) определить действия, выполняемые функцией.

Для задания новых функций в Лиспе используется специальная форма defun:

( defun < имя функции > < параметры > < тело функции >)

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

Пример 1. Написать функцию, складывающую сумму двух чисел.

(defun sum (a b) (+ a b))

Ответ интерпретатора: sum

В рассмотренном примере: sum – имя функции, a и b – ее параметры, (+ a b) – тело функции.

Вызов функции sum для параметров 1 и 2 осуществляется следующим образом:

(sum 1 2)

Ответ интерпретатора: 3

Пример 2. Вызвать функцию sum для вычисления суммы чисел x и y.

(setq x 4)

Ответ интерпретатора: 4

(setq y 5)

Ответ интерпретатора: 5

(sum x y)

Ответ интерпретатора: 9

Передача параметров. Глобальные и локальные переменные

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

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

Пример 3.

(defun f (x) (setq x 'new))

Ответ интерпретатора: f

(setq xold)

Ответ интерпретатора: old

x

Ответ интерпретатора: old

(f x)

Ответ интерпретатора: new

Пример 4.

(defun double (num) (* num 2)

Ответ интерпретатора: double

(setq num 5)

Ответ интерпретатора: 5

(double 2)

Ответ интерпретатора: 4

num

Ответ интерпретатора: 5

Свободные переменные

Если в теле функции есть переменные, не входящие в число ее формальных параметров - они называются свободными. Значения свободных переменных остается в силе после ее выполнения.

Пример 5.

(defun f1 (y) (setq x 3))

Ответ интерпретатора: f1

(f1 5)

Ответ интерпретатора: 3

x

Ответ интерпретатора: 3

Пример выполнения задания

Вычислить зависимость на основе функции . Значение переменной x задать при помощи SET или SETQ.

Программа на Лиспе приняла вид:

(defun cub(a) (* a a a))

Ответ интерпретатора: defun

(setq x 1)

Ответ интерпретатора: 1

(setq y (/ (+ (cub x) (cub (+ x 1))) (cub (+ 1 (* 2 x) (* x x)))))

Ответ интерпретатора: 9/64

y

Ответ интерпретатора: 9/64

Варианты заданий

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

Номер варианта

Зависимость

Функция

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Пример операции с вещественными числами:

(setq x 0.2)

Ответ интерпретатора: 0.2

Пример операции вычисления синуса:

(sin 1.5)

Ответ интерпретатора: 0.997495

Контрольные вопросы

1. Форма defun определения функции пользователя.

2. Передача параметров в функцию.

3. Свободные переменные.

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