- •230400 «Информационные системы и технологии»
- •6 Декабря 2011 г., протокол № 4
- •Оглавление
- •Глава 1. Теория информационных процессов и систем 10
- •Глава 2. Информационные технологии 95
- •Глава 3. Архитектура информационных систем 126
- •Глава 4. Технологии программирования 150
- •Глава 5. Управление данными 239
- •Глава 6. Технологии обработки информации 315
- •Предисловие
- •Глава 1. Теория информационных процессов и систем
- •1.1. Информационные системы. Основные понятия и определения.
- •1.2. Системообразующие свойства информационных систем
- •1.3. Свойства и закономерности систем
- •1.4.Системный подход и системный анализ
- •1.5. Моделирование информационных систем
- •1.5.1. Основные понятия
- •1.5.2. Классификация методов моделирования
- •1.5.3. Математическое моделирование
- •1.6. Теория принятия решений
- •3. Неопределённость наших знаний об окружающей обстановке и действующих в данном явлении факторах (неопределённость природы).
- •4. Неопределённость действий активного или пассивного партнёра или противника.
- •1.7. Информационные процессы
- •Контрольные вопросы
- •Глава 2. Информационные технологии
- •2.1. Состав, структура, принципы реализации и функционирования информационных технологий
- •2.2. Базовые и прикладные информационные технологии
- •Прикладные программные средства включают:
- •2.3. Инструментальные средства информационных технологий
- •Контрольные вопросы
- •Глава 3. Архитектура информационных систем
- •3.1. Классификация информационных систем
- •3.2. Структура, конфигурация информационной системы
- •3.2.1. Информационное обеспечение
- •Классификаторы создаются для решения следующих основных задач:
- •3.2.2. Математическое и программное обеспечение
- •К средствам математического обеспечения относятся:
- •К средствам программного обеспечения (по) относятся:
- •3.2.3. Организационное обеспечение
- •3.2.4. Правовое обеспечение
- •3.2.5. Техническое обеспечение
- •3.3. Процесс разработки информационных систем
- •3.3.1. Выработка или выбор парадигмы программирования
- •3.3.2. Моделирование бизнес-процессов
- •3.3.3. Анализ требований, предъявляемых к ис
- •3.3.4. Разработка архитектуры
- •3.3.5. Кодирование
- •3.3.6. Тестирование информационной системы
- •3.3.7. Документирование
- •3.3.8. Внедрение информационной системы
- •3.3.9. Сопровождение информационной системы
- •Контрольные вопросы.
- •Глава 4. Технологии программирования
- •4.1. Основные понятия программного обеспечения
- •Категории специалистов, занятых разработкой и эксплуатацией программ
- •4.2. Характеристики программного продукта
- •4.3. Жизненный цикл программного продукта
- •4.4.Защита программных продуктов
- •4.5. Классы программных продуктов
- •4.6. Инструментарий технологии программирования
- •4.7. Классификация методов проектирования программных продуктов
- •4.8. Этапы создания программных продуктов
- •1. Составление технического задания на программирование
- •2. Разработка технического проекта
- •3. Создание рабочей документации (рабочий проект)
- •4. Ввод в действие
- •4.9. Структура программных продуктов
- •4.10. Структурное проектирование и программирование
- •4.11. Модульная структура программных продуктов
- •4.12. Алгоритмы
- •4.13. Классификации языков программирования и примеры языков
- •4.13.2. Основы функционального программирования с использованием языка lisp Основные свойства функциональных языков программирования
- •Распространенные языки функционального программирования
- •Основные структуры данных и базовые функции по работе с ними в среде Лисп
- •Контрольные вопросы
- •Глава 5. Управление данными
- •5.1. Основы управления данными
- •5.1.1. Информация, данные и знания.
- •5.1.2.Функции управления
- •5.2.Банки данных в информационных системах.
- •5.2.1.Концепция баз данных
- •5.2.2.Файловые системы и базы данных
- •5.2.4.Классификация банков данных
- •5.3.Моделирование и модели данных
- •5.3.1.Уровни моделирования
- •5.3.2.Виды моделей
- •5.3.3.Модели данных
- •5.3.4.Иерархическая модель данных
- •5.3.5.Сетевая модель данных
- •5.3.6.Реляционная модель данных
- •5.3.7.Постреляционная модель представления данных
- •5.3.8.Многомерные модели представления данных
- •5.3.9.Объектно-ориентированные модели представления данных
- •5.4.Проектирование базы данных
- •5.4.1.Основы реляционной алгебры
- •5.4.2.Инфологический подход к проектированию баз данных
- •5.4.3.Модель «сущность—связь»
- •5.4.4.Переход к реляционной модели данных
- •5.4.5.Пример проектирования реляционной бд средствами субд Access
- •5.5.Субд в архитектуре «клиент-сервер»
- •5.5.1.Открытые системы
- •5.5.2.Клиенты и серверы локальных сетей
- •5.5.3.Системная архитектура «клиент-сервер»
- •5.5.4.Серверы баз данных
- •5.6.Реляционный язык sql
- •Структура sql
- •Контрольные вопросы
- •Глава 6. Технологии обработки информации
- •6.1. Основные виды и процедуры обработки информации
- •6.1.1. Виды обработки информации
- •6.1.2. Основные процедуры обработки данных
- •6.2. Системы поддержки принятия решений (сппр)
- •6.2.1. Условия принятия решений
- •6.2.2. Решение задач с помощью искусственного интеллекта
- •6.2.3. Процесс выработки решения на основе первичных данных
- •6.2.4. Типы информационных систем поддержки принятия решений
- •6.2.5. Реализация процесса принятия решений
- •6.2.6. Средства разработки информационных приложений
- •6.3. Концепция хранилищ и витрин данных, достоинства и недостатки
- •6.3.1. История создания концепции хранилищ данных
- •6.3.2. Причины создания концепции хранилищ данных
- •6.3.3. Факторы и технологии складирования данных
- •6.3.4. Концепция хранилищ данных
- •6.3.5. Взаимное соотношение концепции хранилищ данных и концепций анализа данных
- •6.3.6. Реализации хранилищ данных
- •6.3.7. Субд для аналитических систем
- •6.3.8. Витрины данных
- •6.4. Искусственный интеллект и интеллектуальные системы
- •6.4.1. Цели и задачи искусственного интеллекта
- •6.4.2. Направление исследований в области искусственного интеллекта
- •6.4.3. Структура интеллектуальной системы
- •6.4.4. Разновидности интеллектуальных систем
- •Контрольные вопросы
- •Глава 7. Интеллектуальные системы и технологии
- •7.1. Теория и технологии искусственного интеллекта
- •7.2. Математическое описание экспертной системы, логический вывод
- •7.3. Искусственные нейронные сети
- •7.4. Расчётно-логические системы, системы с генетическими алгоритмами
- •(Начало цикла)
- •Создание начальной популяции
- •Размножение (Скрещивание)
- •Мутации
- •Применение генетических алгоритмов
- •7.5. Мультиагентные системы
- •Контрольные вопросы
- •Глава 8. Инструментальные средства информационных систем
- •8.1. Состав и структура инструментальных средств информационных систем
- •8.2. Тенденции развития инструментальных средств информационных систем
- •8.3. Операционные системы инструментальных средств информационных систем
- •8.4. Технические средства инструментальных средств информационных систем
- •Классификация технических средств инструментальных средств информационных систем.
- •Контрольные вопросы
- •Глава 9. Инфокоммуникационные системы и сети
- •9.1. Модели и структура информационных сетей Классическая модель построения инфокоммуникационных систем
- •9.2. Информационные ресурсы сетей
- •По способу представления:
- •По национально-территориальному признаку:
- •9.3. Теоретические основы современных информационных сетей
- •Контрольные вопросы
- •Глава 10. Методы и средства проектирования информационных систем и технологий
- •10.1. Технология проектирования информационных систем. Этапы проектирования
- •10.2. Методы проектирования информационных систем
- •10.3. Средства проектирования ис
- •Контрольные вопросы
- •Список литературы
- •143 Хорошилов а.В. Селетков с.Н. Днепровская н.В. Управление информационными ресурсами.
Распространенные языки функционального программирования
В настоящее время наиболее распространены следующие языки функционального программирования: Haskell; ML; Ocaml; Erlang; LISP.
Будем рассматривать функциональную парадигму на примере языка программирования LISP.
Лисп (LISP, от англ. LIST Processing — «обработка списков») — семейство языков программирования, основанных на представлении программы системой линейных списков символов, которые являются основной структурой данных языка. Лисп был создан Дж. Маккарти в 1958 году как результат исследований в области искусственного интеллекта, а также продемонстрирован на решении задач символьного дифференцирования и интегрирования алгебраических выражений. Лисп считается вторым после Фортрана старейшим высокоуровневым языком программирования. Несмотря на это, он продолжает развиваться.
Традиционный Лисп имеет строгую динамическую систему типов, содержит императивные свойства, но в основном поощряет функциональную парадигму программирования. Современный Лисп поддерживает также объектно-ориентированное программирование (реализовано на платформе CLOS). Язык Лисп прошёл процесс фундаментальной стандартизации, в результате чего появился стандарт ANSI Common Lisp. Его реализации существуют для большинства платформ. Вот несколько реализаций Lisp:
свободного распространения:
CLISP – под лицензией GNU GPL, доступен для Windows, Macintosh и Linux / Unix; OpenMCL – под лицензией GNU LGPL, доступен для Mac, Linux, FreeBSD, Solaris, Windows (in alpha); CMU Common Lisp – Public License, доступен для Unix и Linux; Steel Bank Common Lisp – производное от CMU Common Lisp (включает компилятор);
коммерческие продукты:
LispWorks – система высокого качества и по разумным ценам для Windows и Linux; Franz Allegro Lisp – высокое качество и высокая стоимость.
В Лиспе также существует ряд диалектов: Scheme, Common Lisp, Emacs Lisp, AutoLisp. Важнейшие примеры программных продуктов, построенных на основе Лисп, – это AutoCAD, текстовый редактор Emacs. Особую роль Лисп также играет в системах компьютерной алгебры (Maxima, Axiom, Mathematica, Reduce). Можно заметить, что практически все перечисленные программные продукты имеют очень большой жизненный цикл – они созданы очень давно и продолжают развиваться в настоящее время.
Основные структуры данных и базовые функции по работе с ними в среде Лисп
Перейдем к описанию основных структур данных языка Лисп и базовых функций работы с ними. В Лисп используются символы и построенные из них символьные структуры. Символы могут состоять из прописных и строчных букв (хотя в большинстве реализаций они отождествляются). Наряду с символами в Лисп используются числа, которые, как и символы, записываются при помощи ограниченной пробелами последовательности знаков.
Символы T, Nil имеют в Лисп специальные названия: T – истина (true), Nil – ложь (false). Эти символы нельзя использовать в качестве имён других объектов. Числа и логические значения T, Nil являются константами, которые вычисляются сами в себя, остальные символы являются переменными, которые используются для обозначения других объектов. Числа и символы представляют собой простейшие объекты – атомы, из которых строятся остальные структуры. Основной тип данных и структура, с которой приходится иметь дело в Лисп – списки. Список – упорядоченная последовательность элементов, ограниченная круглыми скобками, сами элементы отделяются друг от друга пробелами; в качестве элементов могут использоваться атомы или списки. Вот ряд примеров списков: (a s d f); (a b (c d) e); (); nil. Последние два примера представляют список, который не содержит элементов, такой список называется пустым. Атомы и списки называются символьными выражениями или s-выражениями Лиспа. В языке Лисп, с точки зрения синтаксиса, программы и данные не различаются, поэтому любое s-выражение можно интерпретировать как программу.
Важная особенность Лисп – использование префиксной формы записи: сначала записывается операция, затем операнды. Например, обычное выражение 7+9 в Лиспе записывается так (+ 7 9). Это имеет свои преимущества – в выражении 1+2+3+4+5 можно сэкономить на символах «+»: (+ 1 2 3 4 5). Рассмотрим еще ряд примеров вычислений в среде Лисп:
; точка с запятой используются как комментарии в Лисп
;пример 1
;пусть необходимо вычислить 5*3+7
;в Лиспе это запишется так:
(+ (* 5 3) 7) ;после Enter получим ответ:
22
;пример 2
;пусть необходимо вычислить (1+2+3+4)/20
;в Лиспе это запишется так:
(/ (+ 1 2 3 4) 20)
;ответ будет не совсем ожидаемым:
> 1/2
;т. е., Лисп сам динамически получает тип данных – рациональное число,
;как наиболее точное представление результата операции
;при желании всегда можно перейти к вещественным числам:
(float (/ (+ 1 2 3 4) 20))
> 0.5
По умолчанию Лисп использует аппликативный порядок редукций, т. е., перед подстановкой выражения пытается его максимально упростить. От такой попытки упрощения всегда можно отказаться, установив блокировку вычислений. Для того чтобы блокировать вычисление некоторого выражения, достаточно перед ним поставить знак апострофа «'», тогда выражение вычисляется само в себя:
;попробуем вычислить
(1 2 3)
>Error
;Ошибка возникает потому, что Лисп пытается вычислить это выражение,
;используя символ «1» в качестве имени функции, «2», «3» – в качестве её ;аргументов.
;если блокировать вычисление,
'(1 2 3)
;то ошибку уже не получим
> (1 2 3)
Для работы с какой-либо структурой данных в языке программирования Лисп должны быть предусмотрены три механизма: 1) позволяющие разбирать структуру данных на части – селекторы; 2) позволяющие собирать структуру данных из частей – конструкторы; 3) позволяющие проверять различные условия на структуре данных и возвращать T или Nil–предикаты.
В качестве базовых селекторов в языке Лисп используются всего две функции:
Функция CAR (читается «кар») – возвращает в качестве значения первый (головной) элемент списка – аргумента. Тип результата – s-выражение.
Функция CDR (читается «кудр») – возвращает в качестве значения хвостовую часть списка – аргумента. Тип результата – список.
Рассмотрим ряд примеров:
(car '(1 2 3))
;обращаем внимание на блокировку в начале списка (1 2 3), иначе будет ;ошибка
> 1
(car '((1 2) 3))
>(1 2)
(cdr '(1 2 3))
>(2 3)
(cdr '((1 2) 3))
>(3)
(cdr '(3))
>nil
;с помощью этих функций можно добраться до любого элемента в списке
(car (cdr '(1 2 3 4)))
;так получаем второй элемент списка
>2
В качестве базового конструктора в Лиспе используется одна функция: CONS, которая строит новый список из переданных ей в качестве аргументов головы и хвоста. Примеры:
(cons 'a '(b c))
>(a b c)
(cons '(+ 1 2) '(c d))
>((+ 1 2) c d)
(cons (+ 1 2) '(4 5))
;первый аргумент не заблокирован, поэтому перед подстановкой
;вычисляется
>(3 4 5)
В качестве предикатов в Лиспе используется множество различных функций. Рассмотрим некоторые из них.
Функция ATOM – проверяет, является ли аргумент атомом. Аргументом может быть любое s-выражение. Значение предиката равно T, если аргумент является атомом, в противном случае Nil. Примеры:
(atom 'x)
> T
(atom '())
>T
;дело в том, что пустой список является одновременно и атомом и списком
(atom '(a b c))
>Nil
Функция EQL – сравнивает числа одинаковых типов. Предикат нельзя использовать для сравнения списков (для чисел можно также использовать обычный символ «=»). Примеры:
(eql 3 3)
>T
(eql 3 3.0) ;Хотя числа равные, но разных типов
> Nil
(= 5 5)
>T
(eql '(1 2 3) '(1 2 3))
>Nil
Функция EQUAL – работает так же, как EQL, но позволяет сравнивать и списки. Примеры:
(equal 'x 'x)
>T
(equal '(1 2 3) '(1 2 3))
>T
Для того чтобы начать программировать в Лисп, осталось ввести механизм ветвления, а также механизм задания функций.
Ветвление реализуется в Лисп с помощью следующей специальной формы:
(IF (condition) (expression-true) (expression-false))
Здесь condition – условие, которое проверяется;
expression-true – выражение, которое вычисляется и значение которого возвращается в качестве ответа всей формы IF, если условие condition верно;
expression-false – выражение, которое вычисляется и значение которого возвращается в качестве ответа всей формы IF, если условие condition неверно.
Иногда требуется рассмотреть более одного условия (осуществить разбор случаев), тогда может быть полезна следующая форма:
(COND
((condition1) (expression1))
((condition2) (expression2))
…
((condition_n) (expression_n))
(T (expression-else)))
Здесь проверяется условие condition1. Если оно выполняется, то результатом формы COND будет значение выражения expression1 (условия, расположенные ниже, уже не рассматриваются); если condition1 неверно, то проверяется condition2, и если оно верно, то результатом формы COND будет значение выражения expression2 и т. д. Если неверно ни одно из условий condition1, condition2, …, condition_n, то вычисляется выражение expression-else, и его значение возвращается в качестве результата формы COND.
Для задания функции используется специальное служебное слово DEFUN. При этом функция задаётся в следующем виде:
(DEFUN Function-name (list-arg) (body-function))
Здесь Function-name – имя функции;
list-arg – список аргументов функции;
body-function – тело функции.
Рассмотрим ряд примеров:
(if (equal (cdr '(1)) nil) 1 2)
>1
(if (atom '(1 2)) 1 2)
>2
(defun f (x) (+ x 1)) ; определили функцию
>(f 1) ;вычисляем её значение от x=1
>2
(defun g (x y) (if (> x y) (- x y) (* x y)))
>(g 1 2)
>2
>(g 3 2)
>1
(defun h (x)
(cond
((= x 0) 1)
((> x 0) (+ x 1))
(t x)))
>(h 0)
>1
>(h 1)
>2
>(h -1)
>-1
Техники функционального программирования – рекурсия
Рекурсия является одной из важнейших техник функционального программирования.
Функция является рекурсивной, если в её определении содержится вызов этой функции. На рекурсии основана декомпозиция задачи на подзадачи, решение которых, насколько возможно, пытаются свести к уже решенным или к решаемой в настоящий момент задаче. Рекурсия близка к аппарату математической индукции, что определяет удобство реализации индуктивных определений.
Как правило, рекурсивная функция реализует разбор случаев, некоторые из них влекут продолжение процесса вычислений, через вызов рекурсивной функции, другие не прибегают к рекурсии. Последние носят название базис рекурсии. Феномен рекурсии довольно сложен. И иногда он существенно помогает в решении задач. Рассмотрим идеи рекурсии на ряде простых примеров.
Пусть необходимо построить функцию вычисления факториала:
(defun factorial (n)
(if (= n 1)
1
(* n (factorial (- n 1)))))
При вычислении используется так называемая подстановочная модель:
(factorial 6)
(* 6 (factorial 5))
(* 6 (* 5 (factorial 4)))
(* 6 (* 5 (* 4 (factorial 3))))
(* 6 (* 5 (* 4 (* 3 (factorial 2)))))
(* 6 (* 5 (* 4 (* 3 (* 2 (factorial 1))))))
(* 6 (* 5 (* 4 (* 3 (* 2 1)))))
(* 6 (* 5 (* 4 (* 3 2))))
(* 6 (* 5 (* 4 6)))
(* 6 (* 5 24))
(* 6 120)
720
Выделяют следующие способы организации рекурсии:
Простая рекурсия.
Параллельная рекурсия.
Взаимная рекурсия.
Рекурсия высоких порядков.
Общий вид простой рекурсии:
(defun f (...)
(cond ((...) (...)) ((...)( ...(f ...) ...)) ((...)(...))) )
О простой рекурсии говорят в том случае, если вызов функции встречается в некоторой ветви лишь один раз. Простая рекурсия часто эквивалентна циклу.
Определение функции factorial является простой рекурсией. Вот еще пример простой рекурсии – функция append, объединяющая два списка в один:
(defun append (X Y)
(if (Null X) Y (cons (car X) (append (cdr X) Y))))
;здесь предикат Null принимает значение T, если список X пуст,
;Nil — в противном случае.
Общий вид параллельной рекурсии:
(defun f ... (g ... (f ...) ... (f ...) ...) ...)
Таким образом, при параллельной рекурсии тело определения функции f содержит вызов некоторой функции g, несколько аргументов которой являются рекурсивными вызовами функции f. Пример такой функции – вычисление чисел Фибоначчи.
Общее правило для чисел Фибоначчи можно сформулировать так:
если n = 0 , то Fib(n) = 0
если n = 1 , то Fib(n) = 1
в остальных случаях Fib(n)=Fib(n − 1) + Fib(n − 2)
Можно немедленно преобразовать это определение в процедуру Лисп:
(defun fib (n)
(cond ((= n 0) 0)
((= n 1) 1)
(t (+ (fib (- n 1))
(fib (- n 2))))))
Общий вид взаимной рекурсии:
(defun f ... (g ...)...)
(defun g ... (f ...)...)
О взаимной рекурсии говорят в том случае, если определение функции f содержит вызов некоторой другой функции g, которая в свою очередь содержит вызов функции f. Ясно, что в общем случае количество функций, вовлеченных в организацию взаимной рекурсии, может быть больше, чем две. Для примера взаимной рекурсии реализуем функцию turn зеркального отображения списка и всех вложенных в него подсписков.
(defun turn (L)
(cond ((Atom L) L)
(t (permulate L nil))))
(defun permulate (L Result)
(cond ((Null L) result)
(t (permulate (cdr L)
(cons (turn (car L))
result)))))
Общий вид рекурсии высших порядков:
(defun f ... (f ...(f ...)...) ...)
В качестве классического примера рекурсии более высокого порядка часто приводится известная из теории рекурсивных функций функция Аккермана,пользующаяся славой «плохой» функции:
(defun akkerman (m n)
(cond ((= m 0) (+ n 1))
((= n 0) ( akkerman (- m 1) 1))
(t ( akkerman (- m 1)
(akkerman m (- n 1))))))
>(аккерман 2 2)
>7
Вычисление функции Аккермана довольно сложно, и время вычисления растет лавинообразно уже при малых значениях аргумента.