Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab2-Abstracts.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
172.03 Кб
Скачать

стр.30

2. Абстрактное программирование. Функционалы и их применение в вычислительной математике Цель работы

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

  2. Изучение основ функционального стиля программирования.

  3. Изучение способов программирования с помощью функций.

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

  5. Знакомство с особенностями программирования на языке Лисп.

  6. Освоение инструментальных средств разработки функциональных программ.

Содержание работы

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

Организация дружественного диалога с предполагаемым пользователем программы. Тестирование определений. Документирование программы.

Введение в абстрактное программирование

Порядок рекурсии функций считается от 0.

Функционал = функция, имеющая функциональный аргумент (функция >1 порядка).

Применяющие функционалы:

(SETQ plus ‘+).

(APPLY plus ‘(2 3)) -> 5.

$ (FUNCALL plus 2 3)) -> 5.

Отображающие функционалы:

(MAPCAR ‘(lambda (x y) (list x y)) ‘(a b c) ‘(1 2 3)) -> ((a 1) (b 2) (c 3)).

(MAPLIST ‘(lambda (y) y) ‘(a b c)) -> ((a b c) (b c) (c)).

(defun mapcar (f l)((null l) nil)(cons(funcall fn (car l))(mapcar fn (cdr l)))).

Автоаппликативный вариант факториала:

(defun ! (n) (fact ‘fact n)).

(defun fact (f n) ((zerop n) 1) (* n (funcall f f (- n 1))))).

Основные типы функционалов и их применения Применяющие функционалы

(APPLY <функциональный аргумент> <список аргументов> ) 

(<функциональный аргумент> ‘<аргумент-1> ... ‘<аргумент-N>)

где

<функциональный аргумент> ::= <имя функции> |

ямбда–выражение>

<список аргументов> ::= (<аргумент-1> ... <аргумент-N>)

Пример нахождения суммы элементов списка:

(APPLY ‘+ ‘(1 2 3 4 5))  (+ 1 2 3 4 5) -> 14

Пример нахождения произведения элементов списка:

(APPLY ‘* ‘(1 2 3 4 5))  (* 1 2 3 4 5) -> 120

(FUNCALL <функциональный аргумент>

<аргумент-1> ... ‘<аргумент-N>)

(<функциональный аргумент> <аргумент-1> ... <аргумент-N>)

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

(SETQ plus +)

((LAMDBA (f x y) (f x y)) plus 2 3)

 (plus 2 3)  (+ 2 3) -> 5

Необходимо отметить, что в качестве фактического аргумента для f передается синоним имени примитива + а не символ ‘+.

Отображающие функционалы

Пример нахождения суммы квадратов элементов списка:

(MAPCAR ‘(LAMDBA (x y) (+ x y)) ‘(1 2 3 4 5))  (+ 1 2 3 4 5) -> 14

Порядок выполнения работы Основные приемы программирования функционалов

; 1. Применяющие функционалы.

; EVAL

; (eval '(+ 2 3 4 5))

; Лямбда- функции и функциональные аргументы

; (apply '+ '(2 3 4 5))

; (apply '(lambda (x y) (* x y)) '(2 3))

; В AutoLISP имеется встроенная функция MAPCAR с числом аргументов-списков

; в соответствии с арностью функции

; в качестве первого аргумента MAPCAR требует символьное выражение,

; представляющее собой либо имя функции или заблокированное с помощью

; QUOTE или FUNCTION лямбда- выражение.

; Пример. Произведение элементов 2-х списков

(defun ПроизведениеСписков (список1 список2)

(MAPCAR '* список1 список2)

)

;Пример. (ПроизведениеСписков '(1 2 3) '(4 5 6))

;Результат: (4 10 18)

; Пример. Сумма квадратов элементов списка

(defun КвадратыЭлементовСписка (список)

(MAPCAR '* список список)

)

;Пример. (КвадратыЭлементовСписка '(1 2 3))

;Результат: (1 4 9)

; Применение функции из списокФункций к соответствующему элементу из списокДанных

(defun APL-APPLY (списокФункций списокДанных)

(MAPCAR '(lambda (функция элемент) ((EVAL функция) элемент)) списокФункций списокДанных)

)

;Пример. (APL-APPLY '(cdr reverse) '((1 2 3) (4 5 6)))

;Результат: ((2 3) (6 5 4))

; 2.

; Одно из приблизительных описаний MAPCAR может быть следующим.

;Заметим, что, в отличие от MAPCAR в качестве первого аргумента передается

; не символ или заблокированное вычисление а сама функция.

; для случая арности функции 1

(defun Map-Car-1 (функция список)

(if (null список) nil

(cons (функция (car список)) (Map-Car-1 функция (cdr список)))

)

)

; для случая арности функции 2

(defun Map-Car-2 (функция список1 список2)

(if (null список1) nil

(cons (функция (car список1) (car список2)) (Map-Car-2 функция (cdr список1) (cdr список2)))

)

)

;Применение функции последовательно к каждому элементу списка

;Пример. Обращение внутренних подсписков списка:

; (Map-Car-1 reverse '((1 2 3 4 5) (2 3 4 5) (6 7 8)))

;Результат: ((5 4 3 2 1) (5 4 3 2) (8 7 6))

;Пример. Возведение элементов списка в квадрат:

; (Map-Car-1 (lambda (x) (* x x)) '(1 2 3 4 5))

;Результат: (1 4 9 16 25)

;Пример. Поэлементное произведение двух списков:

; (Map-Car-2 (lambda (x y)(* x y)) '(1 2 3) '(5 4 3))

;Результат: (5 8 9 8 5)

(defun КвадратыЭлементовСписка-1 (список)

(Map-Car-1 (lambda (элемент) (* элемент элемент)) список)

)

;или

(defun КвадратыЭлементовСписка-2 (список)

(Map-Car-2 * список список)

)

;Пример. (КвадратыЭлементовСписка-1 '(1 2 3 4 5))

; или (КвадратыЭлементовСписка-2 '(1 2 3 4 5))

;Результат: (1 4 9 16 25)

; 3.

; На практике возникает необходимость в определении большого количества

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

; удобно определить одну универсальную параметризованную функцию высших порядков,

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

; Ниже приводится примерный вариант такого функционала.

(defun Map-Def (проверкаЗавершенияОбработкиСписка

объединениеРезультатов

выборОбрабатываемойЧастиСписка

выборОстальнойЧастиСписка

ПрименяемаяФункцияПользователя

списокПользователя)

(if (проверкаЗавершенияОбработкиСписка списокПользователя) nil

(объединениеРезультатов

(ПрименяемаяФункцияПользователя

(выборОбрабатываемойЧастиСписка списокПользователя)

)

(Map-Def проверкаЗавершенияОбработкиСписка

объединениеРезультатов

выборОбрабатываемойЧастиСписка

выборОстальнойЧастиСписка

ПрименяемаяФункцияПользователя

(выборОстальнойЧастиСписка списокПользователя)

)

)

)

)

; Используя Map-Def можно написать другой вариант функции Map-Сar-1,

; который и будет нами использоваться в дальнейшем.

(defun Map-Car (ФункцияПользователя списокПользователя)

(Map-Def null ; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

car ; выборОбрабатываемойЧастиСписка

cdr ; выборОстальнойЧастиСписка

ФункцияПользователя списокПользователя)

)

;Табулирование функций: получение списка пар значений элементов списка и функций от них. )

(defun ТабулированиеФункции(функция список)

( Map-Car (lambda (элемент) (list элемент (функция элемент))) список)

)

;Пример. Получение списка координат вида (x y) для функции вида y=x^2

;(ТабулированиеФункции (lambda (x)(* x x)) '(1 2 3 4))

;Результат: ((1 1) (2 4) (3 9) (4 16))

; Полезной функцией для дальнейших определений является copy.

; сopy - функция, возвращающая полученное в качестве аргумента значение

(defun copy (элемент) элемент)

; Map-List : Последовательное применение функции к списку и

;последовательно к его подспискам без первого элемента

(defun Map-List (функция список)

(Map-Def null ; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

copy ; выборОбрабатываемойЧастиСписка

cdr ; выборОстальнойЧастиСписка

функция список)

)

;Пример.

;(Map-List copy (1 2 3 4 5))

;Результат: ((1 2 3 4 5) (2 3 4 5) (3 4 5) (4 5) (5))

;Пример. Обращение полученных подсписков

;(Map-List reverse '(1 2 3 4 5))

;Результат: ((5 4 3 2 1) (5 4 3 2) (5 4 3) (5 4) (5))

;Пример. Вычисление произведения полученных подсписков

;(Map-List (lambda (x) (apply '* x)) '(1 2 3 4 5))

;Результат: (120 120 60 20 5)

; Map-Can, Map-Con : аналоги MAPCAR, MAPLIST, но объединяют

; результаты (подсписки) в один список

(defun Map-Can (функция список)

(Map-Def null append car cdr функция список)

)

(defun Map-Con (функция список)

(Map-Def null append copy cdr функция список)

)

;Пример. Вывести только положительные элементы списка:

;(Map-Can (lambda (x) (if (> x 0) (list x) nil)) '(-1 -2 1 2 0 -3 -4 3 4))

;Результат: (1 2 3 4)

;Пример. (Map-Con copy '(1 2 3 4 5))

;Результат: (1 2 3 4 5 2 3 4 5 3 4 5 4 5 5)

;Пример. (Map-Con reverse '(1 2 3 4 5))

;Результат: (5 4 3 2 1 5 4 3 2 5 4 3 5 4 5)

; Map-C, Map-L : аналоги Map-Car, Map-List, но не собирают и необъединяют результаты, а

; возвращают исходный список

(defun Map-C (функция список)

(PROGN (Map-Car функция список) список)

)

(defun Map-L (функция список)

(PROGN (Map-List функция список) список)

)

;Пример. (Map-C (lambda (x) (* x x)) '(1 2 3 4))

;Результат: (1 2 3 4)

;Пример. (Map-L reverse '(1 2 3 4))

;Результат: (1 2 3 4)

;Пример. Вывести элементы списка на экран и вернуть исходный список без изменений

; (Map-C print '(1 2 3 4 5))

;Результат: 1

; 2

; 3

; 4

; 5 (1 2 3 4 5)

;Пример. Функция возвращает исходный список, при этом выводятся на экран все

;хвостовые части исходного списка, начиная с исходного

; (Map-L print '(1 2 3 4 5))

;Результат: (1 2 3 4 5)

; (2 3 4 5)

; (3 4 5)

; (4 5)

; (5) (1 2 3 4 5)

; Вычисление декартова произведения 2-х списков

(defun ДекартовоПроизведение (список1 список2)

(Map-Can (lambda (элемент1) (Map-Car (lambda (элемент2) (list элемент1 элемент2)) список2)) список1)

)

;Пример. (ДекартовоПроизведение '(a b c) '(1 2 3))

;Результат: ((A 1) (A 2) (A 3) (B 1) (B 2) (B 3) (C 1) (C 2) (C 3))

;Проверяет, удовлетворяет ли каждый элемент списка условию

(defun Every (условие список)

(APPLY 'AND (Map-Car условие список))

)

;Проверяет, удовлетворяет ли хотя бы один элемент списка условию

(defun Some (условие список)

(APPLY 'OR (Map-Car условие список))

)

;Пример. (Every (lambda (x) (> x 0)) '(1 2 3 4 5))

;Результат: T

;Пример. (Every (lambda (x) (> x 0)) '(1 2 3 4 5 0 -1))

;Результат: nil

;Пример. (Some (lambda (x) (< x 0)) '(1 2 3 4 5 6))

;Результат: nil

;Пример. (Some (lambda (x) (< x 0)) '(1 2 3 0 -4))

;Результат: T

; Удаление элементов из списка, удовлетворяющих условию

(defun DeleteIf (условие список)

(Map-Can (lambda (элемент)

(if (условие элемент) nil (list элемент))

)

список

)

)

; Удаление элементов из списка, неудовлетворяющих условию

(defun DeleteIfNot (условие список)

(Map-Can (lambda (элемент) (if (условие элемент) (list элемент) nil)) список)

)

;Пример. (DeleteIf (lambda (x) (< x 0)) '(1 2 3 -4 4 5 -6 0 -8 9))

;Результат: (1 2 3 4 5 0 9)

;Пример. (DeleteIfNot (lambda (x) (> x 0)) '(1 2 3 0 9 -4))

;Результат: (1 2 3 9)

; 4.

; Одним из частных случаев списка можно считать матрицу.

; Операции над матрицами являются достаточно распространенными при решении численных задач.

; Поэтому ниже приводятся определения наиболее полезных функционалов,

; предназначенных для манипуляций со строками и столбцами матриц.

; Применение функции к каждому элементу матрицы

(defun Matr-Element (функция матрица)

(Map-Car (lambda (строка) (Map-Car функция строка)) матрица)

)

;Пример. Умножить каждый элемент матрицы на 3

;(Matr-Element (lambda (x) (* x 3)) '((1 2 3) (4 5 6)))

; Результат: ((3 6 9) (12 15 18))

; Первый столбец матрицы

(defun Matr-Car (функция матрица)

(Map-Def null ; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

caar ; выборОбрабатываемойЧастиСписка

cdr ; выборОстальнойЧастиСписка

функция матрица)

)

;Пример. (Matr-Car copy '((1 2 3) (4 5 6) (7 8 9)))

;Результат: (1 4 7)

;Возвращает матрицу без 1-го столбца

(defun Matr-Cdr (функция матрица)

(Map-Car cdr (функция матрица))

)

;Пример. (MATR-CDR copy '((1 2 3)(4 5 6)(7 8 9)))

;Результат: ((2 3) (5 6) (8 9))

;Пример. (MATR-CDR (lambda (x) (Matr-Element (lambda (y) (* y 3)) x)) '((1 2 3)(4 5 6)(7 8 9)))

;Результат: ((6 9) (15 18) (24 27))

;Возвращает список, содержащий саму матрицу, матрицу без 1-го столбца и т.д.

(defun Matr-Map-List (функция матрица)

(Map-Def (lambda (список) (Every null список))

; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

copy ; выборОбрабатываемойЧастиСписка

(lambda (список) (Map-Car cdr список)); выборОстальнойЧастиСписка

функция матрица)

)

;Пример. (Matr-Map-List copy '((1 2 3) (4 5 6) (7 8 9)))

;Результат: (((1 2 3) (4 5 6) (7 8 9)) ((2 3) (5 6) (8 9)) ((3) (6) (9)))

;Список столбцов матрицы

(defun Matr-Map-Car-2 (функция матрица)

(Matr-Map-List (lambda (x) (Matr-Car copy x)) (функция матрица))

)

; или через Map-Def

(defun Matr-Map-Car (функция матрица)

(Map-Def (lambda (список) (Every null список))

; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

(lambda (матрица) (Matr-Car copy матрица))

; выборОбрабатываемойЧастиСписка

(lambda (матрица) (Map-Car cdr матрица)); выборОстальнойЧастиСписка

функция матрица)

)

;Пример.(Matr-Map-Car copy '((1 2 3) (4 5 6) (7 8 9)))

;или (Matr-Map-Car-2 copy '((1 2 3) (4 5 6) (7 8 9)))

;Результат: ((1 4 7) (2 5 8) (3 6 9))

;Транспонирование матрицы (поворот матрицы на 180 градусов)

(defun Matr-Trans (функция матрица)

(Matr-Map-List (lambda (частьМатрицы) (Matr-Car copy частьМатрицы))

(функция матрица))

)

; Пример. (Matr-Trans copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: ((1 4 7) (2 5 8) (3 6 9))

;Поворот матрицы вправо

(defun Matr-RightRotate (функция матрица)

(Matr-Map-List (lambda (частьМатрицы) (Matr-Car copy частьМатрицы))

(функция (reverse матрица)))

)

; Пример. (Matr-RightRotate copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: ((7 4 1) (8 5 2) (9 6 3))

;Поворот матрицы влево

(defun Matr-LeftRotate (функция матрица)

(reverse (Matr-Map-List

(lambda (частьМатрицы) (Matr-Car copy частьМатрицы))

(функция (copy матрица))))

)

; Пример. (Matr-LeftRotate copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: ((3 6 9) (2 5 8) (1 4 7))

;Список матриц, полученных вычеркиванием 1-ых столбца и строки и т.д. до конца

(defun SubMatr-Map-List (функция матрица)

(Map-Def (lambda (список) (Every null список))

; проверкаЗавершенияОбработкиСписка

cons ; объединениеРезультатов

copy ; выборОбрабатываемойЧастиСписка

(lambda (список) (CADR (Matr-Map-List cdr список)))

; выборОстальнойЧастиСписка

функция матрица)

)

; Пример. (SubMatr-Map-List copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: (((1 2 3) (4 5 6) (7 8 9)) ((5 6) (8 9)) ((9)))

;1-я диагональ матрицы (слева направо сверху вниз ; самая левая нижняя - 1-я)

(defun Matr-Diag (функция матрица)

(SubMatr-Map-List (lambda (x) (caar x)) матрица)

)

; Пример. (Matr-Diag copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: (1 5 9)

;Список нижних диагоналей матрицы (слева направо сверху вниз)

(defun Matr-LowDiagList (функция матрица)

(Map-List (lambda (подматрица) (Matr-Diag функция подматрица)) матрица)

)

; Пример. (Matr-LowDiagList copy '((1 2 3) (4 5 6) (7 8 9)))

; Результат: ((1 5 9) (4 8) (7))

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]