Из предисловия Патрика Уинстона ко второму изданию
Никогда не забуду того волнения, которое я испытал, увидев а действии свою первую программу, написанную в стиле Prolog. Эта программа была частью знаменитой системы Shrdlu Терри Винограда (Terry Winograd). Решатель задач, встроенный в систему, работал в "мире блоков" и заставлял руку робота (точнее, ее модель) перемещать кубики на экране дисплея, решая хитроумные задачи, поставленные оператором.
Решатель задач в мире блоков Винограда был написан на языке Microplanner, который, как мы теперь понимаем, был своего рода языком Prolog в миниатюре. Несмотря на все недостатки языка Microplanner, вся работа решателя задач в мире блоков была явно нацелена на достижение определенных целей, поскольку любой язык типа Prolog побуждает программистов мыслить в терминах целей. Благодаря использованию таких целенаправленных процедур, как "схватить", "освободить верх блока", "убрать в сторону", "переместить" и "отпустить", действия этой ясной, понятной и краткой программы казались удивительно интеллектуальными.
Решатель задач в мире блоков Винограда навсегда изменил мое представление о программировании. Я даже переписал этот решатель задач в мире блоков на языке Lisp и привел в своем учебнике по Lisp, поскольку эта программа неизменно впечатляла меня мощью заложенной в ней философии целевого программирования и той легкостью, с какой создаются целенаправленные программы.
Однако обучение целевому программированию на примерах программ Lisp можно сравнить с чтением произведений Шекспира не на английском языке. Это позволяет получить определенное впечатление, но эстетическое воздействие становится гораздо слабее, чем при восприятии оригинала. Поэтому лучшим способом обучения целевому программированию является чтение и написание программ на языке Prolog, поскольку он как раз и предназначен для программирования в терминах целей.
Вообще говоря, развитие языков программирования происходит на пути перехода от языков низкого уровня, в которых программист определяет, как должны быть выполнены те или иные действия, к языкам высокого уровня, позволяющим просто указать, что должно быть сделано. Например, с появлением языка Fortran программисты избавились от необходимости общаться с компьютером на прокрустовом языке адресов и регистров. Теперь они уже могли выражать свои мысли на естественном (или почти естественном) языке, не считая той небольшой уступки, что для этого должны были использоваться ограниченные, 80-колонные перфокарты.
Однако Fortran и почти все другие языки программирования все еще остаются языками процедурного типа, которые требуют точно указывать весь процесс решения задачи. На мой взгляд, современный Lisp достиг абсолютного предела развития языков этого типа, поскольку Lisp (вернее, его версия Common Lisp) обладает непревзойденными выразительными возможностями, но качество создаваемых на ГСРМ программ полностью зависит от того, насколько сможет ими воспользоваться сам программист. А с появлением языка Prolog, с другой стороны, наметился четко выраженный переход к использованию языков декларативного типа, которые побуждают программиста описывать ситуации и формулировать задачи, а не регламентировать во всех подробностях процедуры решения этих задач.
Отсюда следует, насколько важен вводный курс по языку Prolog для всех студентов, изучающих вычислительную технику и программирование, — ведь просто не существует лучшего способа понять, что представляет собой декларативное программирование.
Многие страницы этой книги могут служить хорошей иллюстрацией того различия, которое существует между процедурным и декларативным стилями программистского мышления. Например, в первой главе это различие иллюстрируется на задачах, относящихся к семейным отношениям. Язык Prolog позволяет явно и естественно определить понятие "дед" (grandfather), указав, что дед — это отец (father) одного из родителей (parent). На этом языке определение предиката grandfather выглядит так: grandfather t X, Z) :- father) X, Y) , parent ( Y, Z),
И сразу после ввода в систему Prolog определения предиката grandfather ей можно задать вопрос, например, каково имя каждого из дедов Патрика. Ниже приведен вопрос, который снова сформулирован в системе обозначений Prolog, наряду с типичным ответом.
?- grandfather( X, patrick). X =james/ X = carl
Именно система Prolog должна найти способ решения этой задачи, просматривая в базе данных все, что касается отношений father и parent. Программист указывает только, что дано и на какой вопрос должен быть получен ответ. Он в большей степени обязан предоставить системе нужную информацию, чем алгоритмы, с помощью которых ведется обработка этой информации.
Поняв, что очень важно изучить Prolog, нужно решить, как лучше это сделать. Я убежден, что изучение языка программирования во многом сходно с изучением естественного языка, Так, например, в первом случае можно воспользоваться справочным руководством, а во втором — словарем. Но никто не изучает язык по словарю, поскольку слова — это только часть знаний, необходимых для овладения языком. Для этого необходимо также узнать, по каким правилам формируются осмысленные сочетания слов, а затем приобщиться к высшим достижениям искусства речи под руководством тех, кто владеет литературным стилем.
Точно так же, никто не изучает язык программирования только по справочному руководству, поскольку в нем почти ничего не говорится о том, как используют элементарные конструкции языка те, кто им виртуозно владеет. Поэтому нужен учебник, а признаком хорошего учебника является изобилие примеров, ведь в них сосредоточен богатый опыт, на котором мы в основном и учимся.
В этой книге первый пример появляется уже на первой странице, а далее на читателя как из рога изобилия обрушивается поток примеров программ на языке Prolog, написанных программистом-энтузиастом, горячим приверженцем декларативной идеологии программирования. После тщательного изучения этих примеров читатель не только узнает, как действует система Prolog, но и станет обладателем личной коллекции образцов программ, готовых к употреблению: он может разбирать эти программы на части, приспосабливать каждую часть к своей задаче, а затем снова собирать их вместе, получая при этом новые программы. Такое усвоение предшествующего опыта можно считать первым шагом на пути к овладению мастерством программирования.
Полезным побочным эффектом изучения примеров качественных программ является то, что они позволяют не только освоить само программирование, но и многое узнать об интересной области науки. В данной книге такой научной ДИСЦИПЛИНОЙ, лежащей в основе большинства примеров, является искусственный интеллект. Читатель ознакомится с такими идеями в области автоматического решения задач, как сведение задач к подзадачам, прямое и обратное построение цепочки рассуждений, получение объяснения последовательности рассуждений и объяснения предпосылок, а также освоит различные методы поиска.
Одним из замечательных свойств языка Prolog является то, что он достаточно прост, чтобы студенты могли его использовать непосредственно в процессе изучения вводного курса по искусственному интеллекту. Я не сомневаюсь, что многие преподаватели включат эту книгу в свои курсы искусственного интеллекта с тем, чтобы студенты смогли сами увидеть, как абстрактные идеи приобретают конкретные и действенные формы.
Полагаю, что среди учебников по языку Prolog эта книга окажется особенно популярной, и не только благодаря наличию качественных примеров, но и в связи с другими ее привлекательными особенностями:
• во всех главах книги имеются тщательно составленные резюме;
• все изучаемые понятия подкрепляются многочисленными упражнениями;
• понятие абстракции данных представлено наиболее наглядно — с помощью процедур доступа к элементам структур;
• обсуждению вопросов стиля и методологии программирования посвящена целая глава;
• со всей откровенностью обозначены все трудности, с которыми приходится сталкиваться в ходе программирования на языке Prolog, а не только привлекательные стороны этого процесса.
Все это говорит о том, что перед нами прекрасно написанная, интересная и полезная книга.
Я до сих пор храню первое издание этой книги в своей библиотеке, где она стоит на одной полке с другими выдающимися учебниками по языкам программирования, поскольку обладает такими превосходными особенностями, как ясность и прямота изложения, а также наличие многочисленных примеров, тщательно составленных резюме и многочисленных упражнений. А поскольку эта книга является учебником по языку программирования, мне особенно нравится сделанный в ней акцент на абстракцию данных, внимательное отношение к выбору стиля программирования и непредвзятый анализ не только преимуществ, но и недостатков языка Prolog.
Предисловие