Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
IIS / Лекции / ИИС - Лекции.doc
Скачиваний:
250
Добавлен:
31.03.2015
Размер:
1.6 Mб
Скачать

5.1.2. Языки программирования для разработки иис

Язык символических вычислений Лисп

LISP является сокращением от LISt Processing (обработка списков). Его придумал в 1956-м году профессор Массачусетского технологического института Джон Маккарти со студенческой научной группой для удобной реализации проекта по искусственному интеллекту "Принимающий советы" для анализа и разбора английских фраз. Сначала это были версии для первых компьютеров IBM и DEC. Более-менее законченный вариант LISP 1.5 появился в 1965-м году.

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

Для обработки списков используется функциональная модель, базирующаяся на теории Lambda-исчислений Черча. Фактически программа на Лиспе представляет из себя набор lambda-функций, при этом работа со списками осуществляется с помощью базового набора примитивов типа CAR/CDR (взять первый элемент списка, который сам может быть списком/получить список без первого элемента). Таких примитивов в минимальном наборе всего 13 штук. С их помощью и, главное, благодаря рекурсивной системе обработки информации, Лисп позволяет очень компактно описывать функции, для реализации которых на других языках программирования потребовались бы сотни и тысячи строчек кода. Такие задачи, как автоматическое доказательство теорем, понимание естественного языка и окружающего мира, логические исчисления, написание компиляторов, везде, где требуется обработка абстрактной структурной информации, как оказалось, очень удачно описываются и программируются на Лиспе.

Досталось (и достается сейчас) языку довольно много. Началось все с названия. Имя языка совпадает с английским словом "шепелявить". Представляю, что приходилось выслушивать ЛИСП-программистам по поводу их произношения. Потом языку досталось из-за безумного количества скобок, используемых для записи программ, из-за бедности типов данных (базовых всего два), из-за... список можно продолжить. Но первый компьютерный психиатр "Элиза" был написан именно на ЛИСП'е и только значительно позже переписан на других языках программирования. Первые экспертные системы и системы автоматического доказательства теорем также были исходно реализованы на ЛИСП'е. И это несмотря на бедность средств работы с периферией, контроль типов во время исполненияпрограммы и т. п. Почему же так случилось? Да потому, что ЛИСП - один из немногих языков программирования, который поддерживает функциональный стиль.

Давайте рассмотрим действие некоторой программы P. Она получает на входе некоторый набор (множество) данных М и преобразует его во множество выходных данных M1. То есть программа отображает множество М во множество М1, причем конкретному набору входных данных соответствует конкретный выходной набор. Отображение однозначно! В математике такая зависимость называется функцией, а значит, мы имеем право рассматривать программу как функцию над множеством входных параметров. Кажущаяся сложность определений, полностью окупается тем изяществом, с которым можно писать программы на функциональных языках. Судите сами.

Пусть необходимо реверсировать произвольную последовательность. То есть из конструкции вида (A B C D E F Q) получить (Q F E D C B A). Последовательность может быть произвольной длины и произвольной структуры, то есть вместо любого из атомов А, В, и т. д. может стоять произвольная подпоследовательность. (Вообще, в ЛИСП'е такие структуры называются списками). Решение этой задачи занимает всего несколько строк. Вот оно:

(DEFUN REVERSE-1 (X)

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

(COND ((NULL X) NIL)

; Если аргумент пустой, то ничего не делать (вернуть пустой список)

(T (APPEND (REVERSE-1 (CDR X)) (LIST(CAR X))))))

; Иначе объединить реверсированный список, содержащий все элементы исходного за исключением самого первого (головы), со списком, содержащим голову исходного.

Согласитесь, что три строчки не так много для сформулированной задачи.

Еще функциональное программирование, в том числе и ЛИСП, активно применяется в системах символьных вычислений. Мощнейший аналитический решатель задач REDUCE полностью написан на диалекте языка, называемом R-LISP, а все версии AutoCAD, по 12-ю включительно, поддерживают встроенный язык Авто-ЛИСП, хоть злые языки и утверждают, что ЛИСП был выбран начинающей тогда компанией Autodesk не от хорошей жизни, а от нехватки денег для приобретения "серьезного" языка. А ЛИСП (вместе с исходниками) распространялся свободно. Но это сплетни. А если серьезно, то вряд ли Autodesk поддерживала бы и развивала свой язык, если бы функциональный подход никак себя не оправдывал в компьютерной графике.

После первых впечатляющих успехов актуальной стала задача эффективной реализации языка. Сначала все Лисп -системы были интерпретируемыми, что позволяло достичь определенной гибкости, но сильно замедляло сам процесс работы программы. Автор Лиспа опубликовал в 1965-м году свою книгу "LISP 1.5 Programmer's Manual", в которой описал не просто язык, но и структуру т.н. виртуальной Лисп -машины, некоей абстрактной схемы функционирования Лисп -системы, и формального определения структуры компилятора и интерпретатора. Этот труд стал образцом классического описания языка программирования и его окружения, и на него ссылаются вплоть до сегодняшнего дня. Удивительная ясность и простота Лиспа в сочетании с его мощностью и оригинальной идеологией сделала его не просто языком программирования, а своего рода способом формального описания алгоритмов. Кроме того, идеи, заложенные в Лисп , такие как "сборка мусора", или оптимизация памяти, освобождение ее от "висячих ссылок", актуальны и по сей день.

Где-то к этому времени относится первое совершенное в отношении Лиспа кардинальное изменение, лишившее его основного преимущества перед другими языками -- прозрачности структуры программы. В Лисп был введен примитив PROG, позволяющий писать операторы последовательно, один за одним, как в Фортране или Алголе, и, что самое страшное, добавлен оператор GO (goto), без которого PROG, очевидно, был лишен всякого смысла.

Лисп -машина была реализована в начале 70-х в виде, как бы сказали сейчас, "зашитой в ПЗУ программы", а тогда воплощенной в "железе" для повышения эффективности функционирования, в ряде компьютеров таких фирм, как Xerox и Texas Instruments.

На конец 70-х годов, когда бурно расцвела теория искусственного интеллекта и стали актуальными средства для реализации ее идей, Лисп претерпевает второе рождение. Создается множество диалектов практически для всех платформ и операционных систем, и именно тогда появляются два диалекта, которые стали основоположниками сегодняшних стандартов. Это, прежде всего, Scheme Lisp , который унаследовал от своего родоначальника наиболее чистые черты оригинальной идеологии. Пройдя глубокую математическую переработку, эта версия, по-прежнему ограничиваясь небольшим числом базовых примитивов (полное описание языка занимает всего 50 страниц), позволила сосредоточиться на ключевых деталях при решении ряда математических задач, требующих некоего формального описательного аппарата. Например, оригинальной и многообещающей оказалась идея engines - параллельных процессов. Поэтому в большинстве научных групп используется именно эта версия Лиспа.

Второй диалект, Common Lisp (CL), наоборот, отличался очень большой библиотекой различных функций, чуть ли не превосходящих по количеству аналогичные библиотеки Фортрана (!). Его, конечно, было значительно удобнее использовать для реализации конкретных проектов, требующих, помимо простого анализа списочных структур, еще и больших вычислительных объемов работы и организации хорошего графического интерфейса. Описание этого диалекта занимает уже около 1300 страниц, в него введено довольно много возможностей обычных процедурных языков типа С, например, строгая типизация, которая в оригинальном Лиспе отсутствовала вообще. CL сильно отличается от языка LISP 1.5 60-х годов, и хотя он и включает в себя все базовые возможности, в реальных проектах обычно используется более подходящая человеческой психологии и более близкая к привычным языкам структура программы -- линейная, а не рекурсивная. Однако из-за отказа от оригинальной идеологии, когда требовалось очень четко формализовывать задачу в почти математических терминах, сразу возникли проблемы, характерные для обычных задач проектирования и реализации крупных проектов.

После активного распространения UNIX в 80-х годах получила широкой распространение версия Portable Standard Lisp, реализованная на большинстве платформ, и, наконец, Common Lisp становится фактическим стандартом. А 8-го декабря 1994-го года в Американском Институте Национальных Стандартов было зарегистрировано официальное описание этого языка ANSI X3.226:1994 (X3J13), которое действует и сегодня.

Всплеск интереса к объектно-ориентированному программированию не обошел и Лисп. В него было добавлено понятие объекта, метода, наследования, быстро появился объектный стандарт Common Lisp Object System (CLOS), но при этом его изобретатели не понимали, или не хотели понять, что такое искусственное расширение языка, не соответствующее его идеологии, лишь усложняет Лисп и лишает его как оригинальной ясности, так и эффективности.

Современные реализации Лиспа представляют из себя большие программные комплексы, близкие к CASE-системам. Этот язык относится скорее к 4GL-классу, несмотря на то, что был придуман около 40 лет назад. Манипулирование объектами на абстрактном уровне, хоть и требует подчас конкретного, не визуального, кодирования, тем не менее делает ненужным программирование рутинных операций, а наличие больших библиотек, обеспечивающих быструю реализацию множества примитивов, позволяет получить более эффективный и надежный код, чем при ручном программировании аналогичных задач на С++. Имеется, кстати, большое число "компиляторов", переводящих текст задачи на Лиспе в С-код.

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

Конечно, и стоят такие системы недешево. Например, цена многоплатформенной версии Allegro Lisp 4.2 составляет 4500 долларов, Golden Common Lisp для DOS, Windows, Windows NT и OS/2 стоит $2000, но имеется не меньшее количество и некоммерческих компиляторов, например 32-разрядная версия Allegro Common Lisp 3.0 for Windows, GNU CL для UNIX и т.д. Но наиболее яркое применение Лисп – использование его в знаменитой системе автоматизации проетирования AutoCAD– в ней используется разработанный производителем – компаниейAutoDeskдиалектAutoLisp.

Можно ожидать появления версий и для Интернет. Простой интерпретатор Лиспа на Java уже распространяется бесплатно, а в будущем наверняка появятся и более мощные сетевые диалекты. В силу своей простоты и эффективности этот красивый, но подзабытый в России язык заслуживает не меньшего внимания, чем те же "раскрученные" С и С++.

Язык логического программирования Пролог

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

Идею логического программирования можно сформулировать в двух метафорических равенствах:

  • программа = множество аксиом;

  • вычисление = конструктивный вывод целевого утверждения из программы.

Реализация парадигмы логического программирования оказалась бы нереальной, если бы не существовало эффективных методов организации автоматического поиска доказательств. В 1973 г. группа исследователей из Марсельского университета под руководством Алана Колмероэ, опираясь на исследования Джона Робинсона, посвященные методу резолюций («Машинно-ориентированная логика, основанная на принципе резолюции», 1965), создала программу для доказательства теорем, которая была реализована на языке Фортран. Впоследствии этот продукт получил название Пролог (Prolog — от Programmation en Logique).

Главный компонент интерпретатора этого языка — универсальный механизм решения задач. Чтобы воспользоваться им, программист должен четко описать проблему с помощью фраз Хорна (хорновских дизъюнктов) на языке Пролог. Каждая такая конструкция формулирует некоторое отношение между сущностями из исследуемой предметной области. Для того чтобы запустить механизм решения задачи, нужно написать запрос. После его обработки выясняется, истинный он или ложный. Простейшей фразой Хорна может быть некоторый факт, состоящий из заключения, за которым не следует никаких условий, например

программист(Сергей).

Это выражение можно прочесть как Сергей — программист.

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

Правило — иная форма реализации фразы Хорна, показывающая зависимость одного факта от других. Например, конструкцию языка

знать_пролог(Сергей) :- программист(Сергей).

можно интерпретировать так: Сергей знает Пролог, если он программист.

Приведенное правило и факт содержат явные знания, относящиеся только к человеку по имени Сергей. Однако, развивая конструкцию, правило «знать_пролог» можно обобщить и на всех программистов, если константу <Сергей> заменить переменной X:

знать_пролог(X):-программист(X).

Это выражение можно прочитать следующим образом: Если X — программист, то он знает Пролог. А можно и так: Все программисты знают Пролог.

Рассмотренные выше фразы являются просто объявлениями отношений между сущностями, а Пролог-программы состоят практически исключительно из таких конструкций и не используют управляющих структур, известных из алгоритмических языков программирования, как-то: do, while, for, case и т. д.

В течение ряда последующих лет совершенствовалась теория логического программирования, заметный вклад в развитие которой внесла работа Р. Ковальского «Логика предикатов как язык программирования». А в 1976 г. Ковальский вместе с М. ван Эмденом предложил два подхода к прочтению текстов логических программ — процедурный и декларативный. Однако, несмотря на обилие теоретических работ и передовых идей, концепция логического программирования казалась нереалистичной, безнадежно неэффективной и трудной в осуществлении. Поэтому создание Д. Уорреном и Ф. Перейрой в 1977 г. в университете Эдинбурга интерпретатора/компилятора языка Пролог для ЭВМ DEC-10 полностью развеяло миф о непрактичности логического программирования. Почти весь компилятор написан на Прологе, а алгоритм, использованный при его реализации, послужил прототипом для многих последующих реализаций языка. И наконец, в 1980 г. К. Кларк и Ф. Маккейб в Великобритании разработали версию Пролога для персональных ЭВМ.

В октябре 1981 г. была широко распространена информация о японском проекте создания ЭВМ пятого поколения. В основу методологии разработки программных средств было положено логическое программирование и язык Пролог в частности. Целью проекта декларировалось создание систем обработки информации, базирующихся на знаниях. Тогда же появляется множество коммерческих реализаций Пролога практически для всех типов компьютеров. К наиболее известным можно отнести CProlog, Quintus Prolog, Silogic Knowledge Workbench, Prolog-2, Arity Prolog, Prolog-86, Тurbo Prolo, AmziProlog.

Рассмотрим развитие одной из самых популярных Пролог-систем – TurboProlog.

Большую популярность получила система программирования Turbo Prolog — коммерческая реализация языка для IBM-совместимых ПК. Его первая версия была разработана датской компанией Prolog Development Center (PDC) в содружестве с фирмой Borland International в 1986 г. Система создавалась с серьезными отступлениями от неофициального стандарта языка, самым существенным из которых было введение строгой типизации данных, но это позволило значительно ускорить трансляцию и выполнение программ. Новый компилятор сразу же был по достоинству оценен праграммистами-практиками, хотя и вызвал критику в академических кругах.

В 1988 г. вышла значительно более мощная версия Turbo Prolog 2.0, включающая усовершенствованную интегрированную среду разработки программ, быстрый компилятор и средства низкоуровневого программирования. Кроме того, она предоставляла возможность работы с собственными внешними БД, dBase III и Reflex, интегрированным пакетом Lotus 1-2-3, графическим пакетом Paint Brush и другими приложениями. Фирма Borland распространяла эту версию до 1990 г., а затем компания PDC приобрела монопольное право на использование исходных текстов компилятора и дальнейшее продвижение системы программирования на рынок под названием PDC Prolog.

В июне 1992 г. появилась версия 3.31 — эффективный универсальный инструмент профессиональных программистов, который вскоре стал одним из наиболее широко используемых. PDC Prolog 3.31 работал в среде MS DOS, OS/2, UNIX, XENIX, PharLap DOS Extender, MS Windows. Эта версия была хорошо совместима с традиционными языками программирования, в первую очередь с Си. В ней были расширены возможности создания приложений с интерфейсом GUI (Graphical User Interface), принятым в MS Windows и OS/2. Хотя версия PDC Prolog 3.31 уже включала средства для написания программ, работающих под управлением графических операционных систем, процесс разработки подобных приложений все еще носил рутинный характер. Для того чтобы сделать более простыми, удобными и быстрыми процессы написания, тестирования и модификации приложений на языке PDC Prolog, специалисты Prolog Development Center создали систему программирования под названием Visual Prolog 4.0, выпущенную 7 января 1996 г. В этой работе участвовал коллектив российских программистов под руководством Виктора Юхтенко, который позже стал техническим директором компании «Пролог-Софт», представляющей интересы PDC в России.

При разработке приложений в среде Visual Prolog используется подход, получивший название «визуальное программирование», при котором внешний вид и поведение программ определяются с помощью специальных графических средств проектирования без традиционного программирования на алгоритмическом языке. В результате получили систему программирования, отличающуюся исключительной логичностью, простотой и эффективностью. В Visual Prolog входят различные элементы: прежде всего, интерактивная среда визуальной разработки (VDE — Visual Develop Environment), которая включает текстовый и различные графические редакторы, инструментальные средства генерации кода, конструирующие управляющую логику (Experts), а также являющийся расширением языка интерфейс визуального программирования (VPI — Visual Programming Interface), Пролог-компилятор, набор различных подключаемых файлов и библиотек, редактор связей, файлы, содержащие примеры и помощь. В зависимости от выбранного интерфейса разработчику обеспечивается доступ к множеству генераторов кода (Code Expert), всевозможным ресурсным редакторам и особым дополнительным VPI-предикатам, определениям и библиотекам. Ресурсные редакторы применяются для создания, компоновки и редактирования окон, диалогов, меню, панелей инструментов, строк помощи, строковых таблиц, ярлыков, курсоров, битовых карт и оперативной помощи. Генераторы кода на основе подобных структур создают необходимый первичный Prolog-код. В результате появляется первичный код («скелет»), готовый для компиляции, редактирования связей и выполнения. По желанию программиста генераторы кода могут отобразить любую часть первичного текста программы в окне редактора для просмотра и дополнения в соответствии с логикой приложения, а также для преобразования «скелета» в полноценное приложение.

В декабре 1997 г. фирма PDC выпустила Visual Prolog 5.0, а с января 1999 г. приступила к распространению версии 5.1. В настоящее время все желающие могут бесплатно скопировать через Internet последнюю версию системы Visual Prolog 5.1 Personal Edition, функционирующую в средах Windows 3.1/95/98, NT, OS/2, SCO UNIX и Linux. Ее загрузочный файл объемом 20 Мбайт можно найти по адресам:

http://www.visual-prolog.com/vip/vipinfo/freeware_version.htm,http://www.pdc.dk/vip/vipinfo/freeware_version.htm.

Вариант Personal Edition предназначен для некоммерческого использования, и сообщения об этом постоянно имеются во всех приложениях, созданных с его помощью. Кроме того, владельцы Personal Edition не обеспечиваются бесплатной технической поддержкой и на них не распространяются льготы и скидки при приобретении новых версий. В последней версии появились такие усовершенствования, как отладчик, специальный инструментарий и примеры разработки Web-узлов. Следует отметить, что разрабатывали среду программирования всего три человека.

Все продукты PDC, включая Visual Prolog, — это системы, порождающие исполняемый код (EXE или DLL), что еще раз подтверждает высокую эффективность Пролога.

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

Системы, созданные с помощью продуктов фирмы PDC, применяются в самых разных сферах. Программные комплексы, написанные на VIP, используются в ряде авиационных компаниях для управления движением самолетов и регулирования загрузки авиалиний. Пакет STAFF применяется многими фирмами, в частности, McDonalds, для оптимальной расстановки персонала. В России было создано несколько систем бух- и складского учета с удаленным доступом, в которых возможности Пролога позволяют эффективно проводить различный анализ экономической информации, оптимизировать процессы учета и хранения продукции и т. д.

Практическое применение сегодняшних реализаций Пролога наглядно показывает его преимущества в ряде областей перед традиционными системами программирования. Основное из этих преимуществ - возможность создания программы в терминах решаемой задачи. Бухучет - вы оперируете терминами проводка, сальдо, актив/пассив, квартальный/годовой баланс, а не абстрактными алгоритмическими операторами if, new и goto. Синтаксический разбор запросов на естественном языке -- вы работаете с предложениями, словами и лексемами, а не организовываете циклы для посимвольного анализа строки. Соответственно, для широкого круга задач значительно (до порядка) возрастает скорость разработки, и дополнительно обеспечивается очень высокая надежность программы. А современные профессиональные Пролог -системы обеспечивают скорость работы, не уступающую скорости выполнения аналогичных программ, написанных на Си .

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

Соседние файлы в папке Лекции