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

       

Поиск на лиспе. Функционалы. Свойства символов


ЛЕКЦИЯ 7.

ПОИСК НА ЛИСПЕ. ФУНКЦИОНАЛЫ. СВОЙСТВА СИМВОЛОВ


Содержание

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

Поиск на лиспе. Функционалы. Свойства символов

7.1 Алгоритм поиска на Лиспе.
( Функциональный подход к задаче о фермере,волке,козе и капусте.)

Фермер (Farmer), волк (Wolf), козел (Goat) и капуста (Cabbidge) находятся на одном берегу. Надо перебраться на другой берег на лодке.

Поиск на лиспе. Функционалы. Свойства символов


  • Лодка перевозит только двоих.
  • Нельзя оставлять на одном берегу козу и капусту, козу и волка.

Поиск на лиспе. Функционалы. Свойства символов

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

Процесс перевозки может быть представлен последовательностью состояний. Состояние представляется списком из четырех элементов, каждый из которых отражает размещение объектов F, W, G, C:


(e w e w) - F, G на восточном берегу (e - east);
F W G C - W, C на западном берегу (w - west).

Поиск на лиспе. Функционалы. Свойства символов

Определим две функции:

конструктор - make-state, которая берет в качестве аргументов размещение F, W, G, C

и возвращает состояние

Поиск на лиспе. Функционалы. Свойства символов (defun make-state (f w g c) (list f w g c))

Поиск на лиспе. Функционалы. Свойства символов

и четыре функции доступа, каждая из которых берет состояние и возвращает размещение.

Поиск на лиспе. Функционалы. Свойства символов (defun farmer-side (state)
(nth 0 state))

(defun wolf-side (state)
(nth 1 state))

(defun goat-side (state)
(nth 2 state))

(defun cabbage-side (state)
(nth 3 state))

Поиск на лиспе. Функционалы. Свойства символов

Оставшаяся программа основывается на этих функциях доступа и конструкторах. В частности, они используются для реализации четырех возможных действий фермера:
- перевоз через реку или самого себя или W, G, C.

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

Функция opposite ( определена позже ) определяет новое размещение объектов, которые пересекли реку, а make-state собирает их в новое состояние.

Например, функция farmer-takes-self может быть определена:

Поиск на лиспе. Функционалы. Свойства символов (defun farmer-take-self (state)
(safe (make-state (opposite (farmer-side state))
(wolf-side state)
(goat-side state)
(cabbage-side state))))

Отметим, что эта функция возвращает новое состояние, независимо от того, безопасно оно или нет.


Если состояние безопасно, оно будет возвращено без изменений.
Поиск на лиспе. Функционалы. Свойства символов (defun safe (state)
(cond ((and (equal (goat-side state) (wolf-side state))
(not (equal (farmer-side state) (wolf-side state)))) nil)
((and (equal (goat-side state) (cabbage-side state))
(not (equal (farmer-side state) (goat-side state)))) nil)
(t state)))
Поиск на лиспе. Функционалы. Свойства символов (defun path (state goal)
(cond ((equal state goal))
(t (or (path (farmer-takes-self state) goal)))
(path (farmer-take-wolf state) goal)
(path (farmer-take-goat state) goal)
(path (farmer-take-cabbage state) goal))

Эта версия функции path является простым переводом и содержит несколько ошибок, которые надо исправить. В частности, отметим использование формы OR для управления выполнением ее аргументов.

Напомним,что OR выполняет свои аргументы до тех пор, пока один из них не вернет не-nil величину. Когда это случается, OR завершается без выполнения других аргументов и возвращает это не-nil, как результат.

Таким образом, OR используется не только как логический оператор, но также обеспечивает способ управления поиском пути. OR используется здесь вместо cond, потому что величина, которая тестируется, и величина, которая возвращается в случае не-nil, одна и та же.

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

path от попытки генерировать дочерние состояния от состояния

nil, она ( path), должна сначала проверять, является ли текущее состояние nil, если да, то path должна вернуть nil.

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

Чтобы предотвратить это, в path надо ввести третий параметр, been-list, список всех состояний, которые уже были достигнуты.



Аргумент, значением которого является функция, называют

функциональным аргументом , а функцию, имеющую функциональный аргумент -

функционалом.

Различие между понятиями

"данные" и

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

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

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

Поиск на лиспе. Функционалы. Свойства символов

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

Важный класс функционалов используемых в лиспе -

отображающие функционалы (МАР функционалы)

МАР функционалы - функции, которые некоторым образом отображают (map) список в новый список.

Поиск на лиспе. Функционалы. Свойства символов
MAPCAR один из основных отображающих функционалов.

(MAPCAR f '(x1 x2 x3 ... xN))

MAPCAR функционал имеет два аргумента.

Первый аргумент - функция,

а второй - аргумент список.

Когда MAPCAR выполняется , функция определенная первым аргументом применяется к каждому элементу, списка, определенному вторым аргументом и результат помещает (отображает) в новый список.
Пример,

Поиск на лиспе. Функционалы. Свойства символов * (mapcar 'add1 '( 1 2 3))

(2 3 4)

(MAPCAR f '(x1 x2 x3 ... xN))

эквивалентно

(list (f 'x1) (f 'x2) .... (f 'xN))

Можно использовать в функциях
Поиск на лиспе. Функционалы. Свойства символов (defun list-add1 (lis) (mapcar 'add1 lis))

* (list-add1 '(1 2 3))
(2 3 4)

В качестве аргумента для MAPCAR

может быть использовано значение символа
Поиск на лиспе. Функционалы. Свойства символов * (setq x '(a b (d)))

* (setq y 'atom)

* (mapcar y x)

(t t nil)

Поиск на лиспе. Функционалы. Свойства символов

MAPCAR для нескольких списков

MAPCAR может обрабатывать больше списков, если в функциональном аргументе несколько аргументов.

Поиск на лиспе. Функционалы. Свойства символов
Например

Поиск на лиспе. Функционалы. Свойства символов * (defun addlist (l1 l2) (mapcar '+ l1 L2))

* (addlist '( 1 2 3) '(1 2 3))

(2 4 6)

т.е.

(list (+ 1 1) (+ 2 2) (+ 3 3))

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

Поиск на лиспе. Функционалы. Свойства символов

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

Структура МАР функций ограничивает формы отображаемых функций.

Так, если мы желаем получить список с элементами

Поиск на лиспе. Функционалы. Свойства символов x * x + 1

Мы должны определить функцию

(defun f1 (x) (+ 1 (* x x)))

* (mapcar 'f1 '(1 2 3))

<



/p>

Таким образом определяется специальная функция, которая используется только в MAPCAR.

Аналогично происходит с add1.

Более эффективно в этом случае использовать, т.н.

лямбда выражения:
Поиск на лиспе. Функционалы. Свойства символов (mapcar '(lambda (x) (+ 1 (* x x))) '(1 2 3))

сравни (defun f1 (x) (+ 1 (* x x)))

(mapcar '(lambda (x) (+ 1 x)) '(1 2 3))

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

Лямбда-выражения определяют функцию не имеющую имени.

Общая форма:

(lambda (параметры) )

Поиск на лиспе. Функционалы. Свойства символов

Cвойства символов

В лиспе с символом можно связывать, не только

значение, но и информацию, называемую списком

свойств (property list).

Например, рассмотрим информацию o Mary:

Поиск на лиспе. Функционалы. Свойства символов
aqe 28
occupation lawyer
salary 90
children Bill Alice Susan
свойство значение
Список свойств в этом случае выглядит

(aqe 28 occupation lawyer salary 90 children ( Bill Alice Susan))

Поиск на лиспе. Функционалы. Свойства символов

Чтение свойства

Узнать свойство атома можно используя функцию:

(GET <cимвол> <свойство>) возвращает значение

Поиск на лиспе. Функционалы. Свойства символов * ( get 'Mary 'age)

28

* ( get 'Mary 'children)

( Bill Alice Susan))

* ( get 'Mary 'hobby)

nil

Поиск на лиспе. Функционалы. Свойства символов

Присвоение свойства

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

setf

( setf ( get <символ> <свойство>) <значение>)

Поиск на лиспе. Функционалы. Свойства символов * ( setf ( get 'Mary 'salary) 90)

90

Сначала свойство задается, а затем извлекается. Мы поступили наоборот, хотя в нашем лиспе присутствует функция

putprop:

( putprop <символ> <значение> <свойство>)

<свойство> - нечисловой атом;

<значение> - любое выражение ;

Можно определить

Поиск на лиспе. Функционалы. Свойства символов (defun

putprop ( atom value property)

(setf (get atom property) value))

и использовать при работе со списками.

Свойств у атома может быть много, но у каждого только одно значение.

При внесении нового свойства, оно помещается вначале списка свойств.

Поиск на лиспе. Функционалы. Свойства символов * (putprop 'Mary 'cinema 'hobby)

( hobby cinema .....)

Поиск на лиспе. Функционалы. Свойства символов

Замена свойства

Замена значения свойства производится



повторным присвоением.

Например,

Поиск на лиспе. Функционалы. Свойства символов (putprop 'mary 29 'age)

(get 'mary 'age)

Если возникает необходимость замены текущего значения новым, используя при этом текущее, можно поступить следующим образом:

Поиск на лиспе. Функционалы. Свойства символов (putprop 'mary (+ 1 (get 'mary 'age)) 'age)

Поиск на лиспе. Функционалы. Свойства символов

Удаление свойства

Удаление свойства и его значения производится функцией

(remprop <символ> <свойство>)

Поиск на лиспе. Функционалы. Свойства символов *(remprop 'Mary 'age)

T

Поиск на лиспе. Функционалы. Свойства символов

SYMBOL-PLIST

SYMBOL-PLIST даст информацию о списке свойств

Поиск на лиспе. Функционалы. Свойства символов * ( SYMBOL-PLIST 'Mary)

(aqe 28 occupation lawyer salary 90 children ( Bill Alice Susan))

Поиск на лиспе. Функционалы. Свойства символов


Содержание раздела