Функциональное программирование Лекция 3 (14) Особенности Лиспа.

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



Advertisements
Похожие презентации
Функциональное программирование МарГТУ2009 г. 1 Функции. Базовые функции. Лекция 2.
Advertisements

Работа с файлами Сазонов Д.О. ПМиЭММ Часть 2. Тема занятия: Работа с файлами через потоки Для реализации файлового ввода/вывода, необходимо включить в.
Файловый тип данных Turbo Pascal Операции для работы с файлами 11 класс.
ИМЯ И ЗНАЧЕНИЕ СИМВОЛА Функциональное программирование Григорьева И.В.
Файл это поименованная область диска. Чтобы записать информацию в файл надо проделать следующие операции 1.Открыть файл 2.Вывести данные в файл 3.Закрыть.
Понятие оператора и программы 11 класс. Программирование.
Файловый тип данных Файл – это область памяти на внешнем носителе, в которой хранится некоторая информация. В языке Паскаль файл представляет собой последовательность.
Программирование типовых алгоритмов вычислений Информатика.
Массивы Материалы к урокам по программированию. МАССИВ это УПОРЯДОЧЕННАЯ последовательность данных ОДНОГО ТИПА. Массивы относятся к структурированным.
Строки в Pascal
ФУНКЦИИ БОЛЕЕ ВЫСОКОГО ПОРЯДКА Функциональное программирование Григорьева И.В.
Множества значений или переменных с одним общим именем называются структурированными типами. По способу организации и типу компонентов выделяют: 1. Массивы.
Печать документов Борисов В.А. Красноармейский филиал ГОУ ВПО «Академия народного хозяйства при Правительстве РФ» Красноармейск 2009 г.
Часть 1 Простейшая программа Программа на языке QBASIC состоит из последовательности инструкций – команд компилятору. Если в строке записано несколько.
ВЫЧИСЛЕНИЕ В ЛИСПЕ Функциональное программирование Григорьева И.В.
Текстовые файлы в VBA. Чтобы начать работу с файлом, его необходимо открыть: Open For As # Имя файла – строка, указывающая полный путь к файлу Режим –
Составные типы данных Лекция 8-9. Ломаско Павел Сергеевич9 августа 2012 г.
Файловая переменная. Файл – совокупность данных, записанная во внешней памяти под определенным именем. Любой файл имеет три характерные особенности: уникальное.
Текстовые файлы Вербицкая Ольга Владимировна, Заозерная школа 16.
План-конспект урока (информатика и икт, 9 класс) по теме: Переменные:тип, имя, значение
Транксрипт:

Функциональное программирование Лекция 3 (14) Особенности Лиспа

Содержание 1. Массивы, свойства символов 2. Параметры ( аргументы ) функций 3. Функции интерактивного ввода / вывода 4. Работа с потоками ( файлами ) 2

Для хранения большого количества данных в лиспе используются массивы. Массив - это переменных, ячеек, имеющих одно имя, но разные номера, обеспечивающие доступ к этим ячейкам. Массивы 1

Определение массива Для определения массива заданной размерности используется функция make-array (make- array ) поддерживаются только одномерные массивы - векторы. Пример : > (setq data (make-array 10)) # ( ) ; data - имя массива, ; 0 - начальное наполнение. 4

Доступ к ячейке массива Доступ производится с помощью функции aref. AREF имеет два аргумента - имя массива и индекс и возвращает значение ячейки (aref ) > (aref data 8) NIL; так как там записан NIL. Особенности : первый аргумент не блокируется, первая ячейка имеет номер 0. 5

Запись данных в массив Поместить данные в массив можно, используя функцию setf > (setf (aref data 2) 'dog) aref - вызывает значение ячейки, функция setf помещает значение. Рассмотрим массив testdata > (setq testdata (make-array 4)) #(NIL NIL NIL NIL) > (setf (aref testdata 1) 'dog) > (setf (aref testdata 0) 18) > (setf (aref testdata 2) '(a b) ) > (setf (aref testdata 3) 4 ) Можно проще : (setq testdata ( vector 18 'dog '(a b) 0)) В результате получим : #(18 DOG (A B) 0) Можно использовать эти данные : > (cons (aref testdata 1) (list (aref testdata 3)(aref testdata 2))) (DOG 0 (A B)) > (aref testdata (aref testdata 3)) 18 6

Пример обработки массива Так как доступ к элементам массива производится по номерам, то удобно использовать численные итерации и рекурсии. Рассмотрим функцию, которая берет два аргумента имя массива и его длину и возвращает все значения, помещенные в список (defun array-list (arnam len) (do (( i 0 ( + 1 i)) ( result nil (append result (list (aref arnam i))))) (( equal i len) result) )) > (array-list testdata 4) ( 18 dog (a b) 0) (*) Длина массива : (array-length ) возвращает длину массива. (array-length testdata) возвращает длину массива 4. 7

Аналог ассоциативных массивов … C войства символов 1.2

Что такое свойства символов Символ – атомарная последовательность букв и цифр ( содержащая хотя бы одну букву, в отличие от атома ). > (symbolp '1a) > (symbolp '12)> (atom '12) T NILT В лиспе с символом можно связывать, не только значение, но и информацию, называемую списком свойств (property list). Общий формат : ( свойство1 значение_свойства1 свойство2 значение_свойства2 … ) Например, рассмотрим информацию o Mary: свойство значение aqe 28 occupation lawyer salary 90 children Bill Alice Susan Список свойств в этом случае условно выглядит так : (aqe 28 occupation lawyer salary 90 children ( Bill Alice Susan)) 9

Чтение свойства Узнать свойство атома можно используя функцию : (GET ) ; возвращает значение > ( get 'Mary 'age) 28 > ( get 'Mary 'children) ( Bill Alice Susan)) > ( get 'Mary 'hobby) nil 10

Присвоение свойства Чтобы задать свойство необходимо использовать обобщенную функцию присвоения : ( setf ( get ) ) > ( setf ( get 'Mary 'salary) 90) 90 Сначала свойство задается, а затем извлекается. Мы поступили наоборот, хотя в XLisp присутствует функция putprop: ( putprop ) ; - нечисловой атом; ; - любое выражение ; Хотя можно ее определить самостоятельно : > (defun putprop ( atom value property) (setf (get atom property) value)) и использовать при работе со списками. Свойств у атома может быть много, но у каждого только одно значение. При внесении нового свойства, оно помещается вначале списка свойств. > (putprop 'Mary 'cinema 'hobby) ( hobby cinema.....) 11

Замена свойства Замена значения свойства производится повторным присвоением. > (putprop 'mary 29 'age) > (get 'mary 'age) Если возникает необходимость замены текущего значения новым, используя при этом текущее, можно поступить следующим образом : > (putprop 'mary (+ 1 (get 'mary 'age)) 'age) … хотя удобнее определить свою функцию на основе приведенного примера 12

Удаление свойства Удаление свойства и его значения производится функцией (remprop ) >(remprop 'Mary 'age) T 13

Список свойств Функция SYMBOL-PLIST даст информацию о списке свойств > ( SYMBOL-PLIST 'Mary) (aqe 28 occupation lawyer salary 90 children ( Bill Alice Susan)) 14

Некоторые особенности их определения Параметры ( аргументы ) функций 2

Задание параметров При определении функции можно использовать механизм ключевых слов для того чтобы при вызове функций аргументы трактовать по разному. С помощью ключевых слов можно выделить : необязательные аргументы (optional) параметр, связываемый с хвостом списка аргументов изменяющейся длины (rest) ключевые параметры (key) Ключевые слова начинаются с символа & и их записывают перед соответствующими параметрами в списке. Действие ключевого слова распростроняется до следующего ключевого слова. Параметры, перечисленные в списке до первого ключевого слова, являются обязательными. 16

Необязательные параметры Можно определить необязательные аргументы для вашей функции. Любой аргумент после символа &optional необязательный : > ( Defun bar ( x &optional y) ( if y x 0 )) Bar > ( Defun baaz ( &optional ( x 3 ) ( z 10 )) ( + x z) ) BAAZ > ( bar 5 )> ( bar 5 t)> ( Baaz 5 )> ( Baaz 5 6 ) > (Baaz) Можно вызывать функцию bar или с одним или с двумя аргументами. Если она вызвана с одним аргументом, x будет связано со значением этого аргумента и незаданный аргумент y будет связан с nil; если она вызвана с двумя аргументами,x и y будут свя - заны со значениями первого и второго аргумента, соответственно. Функция baaz имеет два необязательных аргумента. Кроме этого она определяет недостающие зн a чения для каждого из них : если пользователь определит только один аргумент, z будет связано с 10 вместо nil, и если пользователь не определит никаких аргументов, x будет связана с 3 и z с 10. Такое определение значений называется определение по умолчанию. 17

Переменное количество аргументов Вы можете задавать вашу функцию принимающей любое число аргументов, заканчивая список аргументов &rest параметром. LISP будет собирать все аргументы не попавшие в обязательные параметры в список и связывать &rest параметр с этим списком. Итак : > ( Defun foo ( x &rest y) y) FOO > ( Foo 3 ) NIL > ( Foo ) (5 6) > ( defun fn ( x &optional y &rest z)) (list x y z)) fn > (fn 'a) (A NIL NIL) 18

Ключевые параметры Можно задать функции другой вид необязательного аргумента называемого аргументом ключевого слова. Пользователь может задавать эти аргументы в последующем в любом порядке, потому что они маркированы ключевыми словами. Символы t и nil называются константами - символами, потому - что они при выполнении дают сами себя. Существует целый класс таких символов, которые называются ключевыми словами ; любой символ, чье имя начинается с двоеточия является ключевым словом. Примеры использования ключевых слов : > :this-is-a-keyword :THIS-IS-A-KEYWORD > ( Defun foo ( &key x y) ( cons x y) ) FOO > ( Foo :x 5 :y 3 ) (5. 3) > ( Foo :y 3 :x 5 ) (5. 3) > ( Foo :y 3 ) ( NIL. 3 ) > (Foo) (NIL) 19

Значения по умолчанию Ключевой (&key) параметр может иметь также значение по умолчанию : >( Defun foo ( &key ( x 5 )) x ) FOO > ( Foo :x 7 ) 7 > (Foo) 5 > (defun test ( x &optional (y 3) (z 4) &rest a) (cons z ( list x a y))) > (test 1 2 3)> (test 1)> (test 3 4 5) (3 1 NIL 2)(4 1 NIL 3)(5 3 NIL 4) >(test ) (1 3 (1 2 3) 2) 20

Интерактивный режим Функции ввода / вывода 3

Функции печати PRINT печатает значение аргумента без пробела и перевода на другую строку : > (progn (print 1) (print 2) (print 3)) 123 СТРОКИ - последовательность знаков заключенная в кавычки. СТРОКА - специальный тип данных в лиспе. Это атом, но не может быть переменной. Как у числа значение строки сама строка. > "(+ 1 2)" > "string" "(+ 1 2)" "string" Строки удобно использовать для вывода с помощью оператора PRINC: печатает строки без "", печатает аргумент без пробела и перевода строки, обеспечивает гибкий вывод. > (progn (setq x 4) (princ " x = ") (prin1 x) (princ " m ")) x = 4 m ; " m ": значение последнего аргумента. TERPRI производит перевод строки. Как значение возвращает nil. > (progn (setq x 4) (princ "xxx ") (terpri) (princ "xox ")) xxx xox " xox" 22

Чтение данных Для чтения атомарных данных удобно использовать функцию READ Формат ( все параметры – необязательные ): (read [ [ [ [ ]]]]) - входной поток ( по умолчанию : NIL ~ *standard-input*, T ~ *terminal-io*) - если Т, то возвращается ошибка, если достигнут конец файла, если NIL - то - значение, возвращаемое при достижении конца файла ( по умолчанию – NIL) - флаг рекурсивного ввода функция возращает прочитанное выражение Пример : ввод списка с клавиатуры : (defun read-list () (princ "input list: ") (setq l (read))) > (read-list) input list: (1 2 3) (1 2 3) > l (1 2 3) 23

Пример диалогового интерфейса (defun calc (l) (list l)) (defun read-list () (princ "input list: ") (setq l (read))) (defun run () (princ "enter command (c - calculate; q - quit): ") (terpri) (if (eq (read) `c) (progn (read-list) (print (calc l)) (terpri) (d) ) `end )) > (RUN) enter command (c - calculate; q - quit): c input list: (1 2 3) ((1 2 3)) enter command : ? - calculate; q - quit 24

При вводе и выводе информации в Лиспе используется понятие потоков - stream Для потока определены ИМЯ, операции открытия open операции закрытия clouse направления output и input Входные и выходные потоки 4

Загрузка программы Можно сразу загружать программу и начать ее выполнение, для этого используют функцию load: (load ) Записываются обычным образом, но кавычки надо использовать двойные : (load " С :\lisp\prog.lsp") Выполнение ( интерпретация ) программы начинается сразу после ее загрузки. (setq s "Hello World!") ; сохранили в файл prog.pl > (load "prog.pl") ; loading "prog.pl" T > s "Hello World!" 26

Определение выходных и входных потоков Для открытия файла для записи задается его имя, производится операция open и указывается направление output: > (setq our-output-stream (open "sesame" :direction :output)) Зададим значение переменной > (setq s 'e) Можно вывести это значение в файл > (princ s our-output-stream) ; Можно занести список > (print '(a b c d) our-output-stream) Чтобы правильно закрыть поток необходимо в конец поместить > (terpri our-output-stream) Затем файл закрывается > (close our-output-stream) Можно посмотреть информацию в файле. Откроем файл для чтения : > (setq our-input-stream (open "sesame" :direction :input)) Прочитаем информацию > (read our-input-stream) Закроем файл > (close our-input-stream) 27

Чтение символов из файла Предположим, что в файле хранится символьная информация, необходимая нам для обработки. Причем нас интересует каждый символ в файле. До сих пор мы могли вводить только атомы, числа и списки. Сформируем файл : > (setq s "---+++") > (setq p "+++---") Определим поток вывода (setq our-output-stream (open "picture.spl" :direction :output)) (princ s our-output-stream) ; записываем первую стороку (terpri our-output-stream) ; заканчиваем ее (princ p our-output-stream) ; записываем вторую строку (terpri our-output-stream) ; заканчиваем файл Теперь файл закрывается (close our-output-stream) В файле теперь находится : Для чтения символов из файла будем использовать функцию : (READ-CHAR ) Данная функция позволяет читать печатные символы (CHAR) из файла. В качестве значения получается десятичное представление кода символа. Используем ее для посимвольного ввода / анализа информации из файла. 28

Чтение из файла Определим входной поток ( файл ): > (setq our-input-stream (open "picture.spl" :direction :input)) Для чтения символа используем : (read-char our-input-stream) Будем получать последовательность значений и т. д. Для восстановления содежимого файла применяется перекодировка : (setq x (read-char our-input-stream) Содержимое x можно показать : (cond (( = x 43) (prin1'+)) (( = x 45) (prin1 '-)) (( = x 10 ) (terpri))) Можно представить информацию без искажений, если использовать цикл : (loop (progn (setq x (read-char our-input-stream) ) (cond (( = x 43) (prin1'+)) (( = x 45) (prin1 '-)) (( = x 10 ) (terpri)))))) После вывода имеем : Закрытие входного потока : > (close our-input-stream) 29

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

Дополнительное задание Реализуйте экспертную систему, из л. р. 5 на Лиспе. Требования : Интерактивный ввод данных ( диалоговый пользовательский интерфейс ) Запись / чтение базы знаний ( фактов ) в текстовый файл Возможность пополнения имеющейся базы знаний 31