Это прологично!

Благодаря революции искусственного интеллекта 50-летний язык переживает возрождение популярности.

Читатели, интересующиеся языками программирования, несомненно знают идею о том, что какой-либо язык является “ароматом месяца”. Однако, в интересах точности, мы должны признать, что фраза “аромат года” или, более вероятно, “аромат десятилетия” была бы более подходящей. (Более того, вы наверняка узнаете названия некогда популярных языков, которые теперь стали лишь достоянием истории. Действительно, как только язык проходит пик своей популярности, мы можем подумать, что неуклонное падение в безвестность, безусловно неизбежно, и обычно так и происходит. Но статистика показывает один язык, опровергающий эту тенденцию, возвращаясь из мертвых. Этот язык – Prolog, и возрождение его судьбы в немалой степени связано с революцией в области искусственного интеллекта (Al).

Prolog – наша тема, но это не разоблачение еще одного языка, потому что Prolog, конечно, не является “также запущенным” языком программирования. Напротив, рассказывая о Prolog, мы познакомим вас с языком, который, по всей вероятности, совершенно не похожим ни на один другой язык, который вы когда-либо видели раньше. Действительно, как мы увидим, он поддерживает совершенно иную парадигму программирования, чем Python, C++, Java, C# или даже большинство золотых старичков, таких как FORTRAN, COBOL, PL/1 или Algol.

Воскрешение Prolog

Prolog не весенний цыпленок – в 2022 году ему исполняется полвека. Разработанный в сотрудничестве университетов Экс-Марселя и Эдинбурга и представленный в 1972 году, он был разработан специально для программирования приложений Al. В частности, обработка естественного языка считалась его сильной стороной. Он не был первым таким языком – на это право претендует Lisp (см. вставку), но даже сегодня в мире не так много специализированных языков для Al-приложений. О, и на всякий случай, если вам интересно название, это сокращение от PROgramming in LOGic. Это то, что станет более понятным, когда мы начнем рассматривать язык более подробно.

Альтернатива LISP

Одним из самых ранних языков программирования Al, предшествующим Prolog на 14 лет, является Lisp. Он считается вторым старейшим языком высокого уровня, используемым до сих пор. Расшифровываясь как List Processing, он сильно отличается от Prolog, несмотря на то, что эти два языка имеют общие цели. Поэтому, если вас укусил жучок Prolog’а, возможно, вам захочется попробовать и Lisp.

Учитывая, что Lisp, как и Prolog, был разработан для программирования Al-приложений, возможно, не слишком удивительно, что это декларативный язык. Но, по-видимому, в этом отношении они не совсем одинаковы, поскольку декларативные языки делятся на логические, функциональные и языки баз данных, причем Prolog относится к первому лагерю, а Lisp – ко второму. Программы на Lisp состоят исключительно из списков, каждый из которых заключен в круглые скобки. В качестве небольшого отступления к статье о Prolog мы можем лишь надеяться дать самое скудное представление о Lisp, но, возможно, следующий код даст представление о нем. Итак, это не Al-related, и это не декларативно, но следующий код определяет рекурсивную функцию factorial, а затем использует ее для вычисления и записи значения факториала 5. Вы можете попробовать его на https://ideone.com/I/common-lisp-clisp и убедиться, что он действительно дает ожидаемый ответ 120:

(defun factorial (n)
(if (=n 1)
1
(* n (factorial (- n 1)))))
(write (factorial 5))

Мы хотели бы сказать, что Prolog был впервые реализован в Unix, наиболее близком к Linux в 1972 году, но в действительности он впервые появился на мэйнфреймах IBM в малоизвестной сейчас операционной системе под названием CP/CMS. Однако мы можем сказать, что необычно для коммерческого программного обеспечения 70-х годов, CP/CMS была с открытым исходным кодом, и многие пользователи участвовали в ее доработке. Вскоре последовали версии Unix – десятками, что неудивительно в эпоху стольких несовместимых аппаратных архитектур – и сегодня Linux Prolog’и не являются дефицитом, как вы можете увидеть в блоке Опробуйте.

Опробуйте

Читать о Prolog в вашем любимом журнале FOSS – это хорошо, но попробовать самому – еще лучше. К счастью, в ресурсах недостатка нет. SWI-Prolog, вероятно, является самой распространенной реализацией в Linux, а GNU Prolog и YAP (Yet Another Prolog) также имеют энтузиастов. Кроме того, существует еще как минимум пять Prolog для Linux.

Однако, если вы не планируете делать больше, чем пробовать и модифицировать несколько примеров Prolog, просто чтобы получить представление о нем, вам не нужно устанавливать то, что вы будете использовать всего несколько раз. Помимо того, что SWI-Prolog можно запустить локально – он находится не более чем на веб-странице, и эта онлайн-реализация настоятельно рекомендуется.

Перейдите на https://swish.swi-prolog.org. Он представлен как IDE и достаточно интуитивно понятен. Просто введите свой код слева, введите запрос с помощью подсказки ?- справа внизу, а затем нажмите Run! Все в порядке, результат запроса появится в правом верхнем углу, и он может включать графику.

Онлайн-имплантация SWISH предлагает IDE, примеры программ и многое другое.

Особенно интересно, что веб-страница SWISH Prolog поставляется с несколькими примерами, так что вам даже не придется начинать с нуля или искать сторонние примеры кода, чтобы получить первые ощущения от Prolog.

Но как насчет воскрешения Prolog? Один из лучших способов узнать о тенденциях в популярности языков программирования является изучение таблиц индексов TIOBE, которые публикуются ежемесячно. В последней таблице Prolog занимает 20-е место по популярности, если судить по количеству запросов в различных поисковых системах. Возможно, это довольно низкая позиция по сравнению с Python и Java, но она выше, чем была на протяжении большей части 21-летней истории TIOBE, который также включает несколько цифр, полученных до создания TIOBE, в том числе третье место для Prolog в 1987 году.

Хотя изменение судьбы Prolog является темой, выходящей за рамки Linux – и это удручающий факт, что большая часть сегодняшней работы над Al является коммерческой и с закрытым исходным кодом – несколько слов об Al и Linux будут уместны, хотя мы могли бы написать целые статьи на эту тему.

Помимо множества реализаций Prolog для Linux, а в реализации Linux Lisp тоже нет недостатка, интересно посмотреть на другие бесплатные инструменты и проекты с открытым исходным кодом для Linux, связанные с Al. На самом деле, Linux Foundation очень оптимистично смотрит на будущее Linux и открытого кода в Al, и не без основания. Во-первых, если вы предпочитаете придерживаться более традиционных языков программирования чем Prolog или Lisp, существуют библиотеки Al для таких языков, как C, C++ и Python. Кроме того, существует множество фреймворков для Al и машинного обучения, таких как Caffe, NuPIC и H20, избавляющих от необходимости реализовывать Al-приложения на обычном языке. В качестве альтернативы, если вы хотите внести свой вклад в существующий проект, проекты Al с открытым исходным кодом не являются дефицитом. Например, Mycroft Al – это альтернатива с открытым исходным кодом коммерческим приложениям голосового помощника, таким как Amazon’s Alexa. Не забудьте также взглянуть на IBM Watson, в котором рассматривается громкое достижение Linux Al.

IBM WATSON

Возможно, вы помните, что в 2011 году компьютер IBM под названием Watson участвовал в американской телевизионной викторине “Jeopardy!”, сразившись с двумя самыми успешными участниками шоу, и победил.

В IBM рассказали, почему этот подвиг оказался таким грандиозным. “Вопросы в этом шоу полны тонкостей, каламбуров и игры слов – тех вещей, которые восхищают людей, но подавляют компьютеры. “Что такое “Черная смерть коммивояжера”?” – правильный ответ на подсказку Jeopardy! “Красочная чума 14 века, ставшая хитом пьесы Артура Миллера”. Единственный способ получить этот ответ – собрать воедино кусочки информации из различных источников, потому что точный ответ вряд ли где-нибудь написан”.

Watson обладал серьезной вычислительной мощью: в его распоряжении было не менее 10 стоек с 90 серверами Power 750, на которых хранилась информация, эквивалентная одному миллиону книг. Нет необходимости упоминать что настоящим ключом к успеху было программное обеспечение Al. Названное DeepQA – это программное обеспечение работает под управлением Linux, хотя и коммерческого варианта в виде SUSE Linux Enterprise Server от Novell. И это становится еще лучше, учитывая тему этой статьи. Да, вы угадали, хотя DeepQA написана на нескольких языках программирования, включая Java и C++, одним из них является 50-летний ветеран – Prolog.

Программа DeepQA от IBM Watson, которая победила в викторине Jeopardy! (русская адаптация – Своя игра) была частично написана на языке Prolog и работала под управлением Linux.

Что, никаких инструкций?

Когда мы говорили, что Prolog, вероятно, не похож ни на что, что вы когда-либо видели, мы не преувеличивали. И мы не просто говорим, что он странный, как ультратерриториальный APL, или, с другой стороны, длинный и извилистый COBOL, который, несомненно, выглядит более чем странно для современных кодеров. Мы хотим сказать, что программа Prolog не является последовательностью инструкций в обычном смысле этого слова: а именно, списком объектов, выполняющихся последовательно. Языки, поддерживающие последовательные инструкции, включая подавляющее большинство, о которых вы слышали, называются императивными языками. В отличие от них, Prolog является декларативным языком.

Чтобы ответить на очевидный вопрос, декларативный язык программирования – это язык, в котором программа определяет логику проблемы, но не управление потоком, который требуется для ее решения. В качестве примера приведем тривиально простой код Prolog:

male(john). 
male(ian).
female(mary).
parent(mary,john). 
parent(ian,john).
father(X,Y) :- parent(X,Y), male(X).
mother(X,Y) :- parent(X,Y), female(X).

Как мы и обещали, он не похож на программу на большинстве языков, но мы в состоянии его интерпретировать. Первые четыре строки – это примеры так называемых фактов и их значения достаточно интуитивно понятны. Так, например, мы видим, что mary определена как женщина, а также определено, что она является родителем john. Следующие две строки – это примеры правил. Если взять первое правило, то утверждение гласит, что X является отцом Y, если X является родителем Y и X – мужчина, так что :- фактически является IF, а запятая – AND.

Следует сделать несколько общих замечаний. Во-первых, переменные – в нашем примере X и Y – всегда начинаются с заглавной буквы или подчеркивания. Во-вторых, утверждения Prolog должны заканчиваться точкой. И в-третьих, утверждения могут быть разбиты на несколько строк, и это может сделать код более читабельным. Так, например, в определении правила отца мы могли бы поместить два условия после :- на отдельные строки и сделать отступ.

Имея эту программу, мы можем делать запросы, которые вводятся с помощью подсказки ?-. В разных реализациях Prolog есть разные способы добраться до этой подсказки. Так, если мы сделаем запрос male(john), Prolog ответит True (или Yes в некоторых реализациях), что неудивительно, поскольку это было определено как факт. Более сложные запросы, поскольку ответы зависят как от фактов, так и от правил, это mother(mary,john) и father(mary,john), на которые будут получены ответы True и False (или No) соответственно. В качестве альтернативы, если задать запрос female(X), то есть спросить, кто является женщиной, то будет получен ответ X=mary. Если на такие запросы есть более одного ответа – Вы сможете просмотреть их все по очереди, хотя метод перехода от одного ответа к другому зависит от реализации. Так, например, запрос parent(X,john) даст ответы X=mary и X=ian.

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

За пределами основ

Примеры, подобные тем, что мы видели до сих пор, обычно приводятся для того, чтобы дать студентам первое представление о Prolog. Но Вы можете пожелать сделать с его помощью гораздо больше, чем просто помочь разобраться в отношениях в вашем семейном древе.

На одной из улиц Катманду в ряд стоят пять разноцветных домов, в каждом из которых живут жители разной национальности. У каждого жителя есть свое домашнее животное, он курит сигареты разной марки и пьет разные напитки. Англичанин живет в красном доме. У испанца есть собака. В зеленом доме они пьют кофе. Белорус пьет чай. Зеленый дом находится рядом с белым домом. Эта эклектичная коллекция жителей продолжается. У курильщика Winston есть змея. В желтом доме курят Kool (марка ментоловых сигарет). В среднем доме пьют молоко. Норвежец живет в первом доме слева. Курильщик Честерфилда живет рядом с человеком с лисой. В доме рядом с домом с лошадью курят Kool. Курильщик Lucky Strike пьет сок. Японец курит Kent. Норвежец живет рядом с синим домом. Кому принадлежит зебра и кто пьет воду?

Эта задача, иногда называемая “Загадка зебры”, или вариант на эту тему, приписывается Альберту Эйнштейну. Она была популяризирована статьей в журнале Life International в 1962 году. Действительно, случайное использование фирменных сигарет сразу же относит эту головоломку к тому времени, когда курение в некоторых кругах не считалось антисоциальным, но мы отвлечемся.

Эйнштейн подсчитал, что только два процента людей могут решить ее в своей голове, на самом деле, ее до сих пор нетривиально решить с помощью ручки и бумаги, так что это классическая проблема Al, и она может быть легко решена на языке Prolog. На самом деле, программа на Prolog содержит не намного больше фактов, чем те, которые появляются в описании проблемы. Например, ниже приведены первые четыре подсказки, переведенные с английского на язык Polog:

member(h(english,_,_, ,red), Hs),
member(h(spanish,dog,_,_,_), Hs),
member(h(_,_,_,coffee,green), Hs),
member(h(ukrainian,_,_,tea,_), Hs),

Они завершаются запятыми, а не обычной полной остановкой/точкой, потому что это не факты Prolog, а части правила. Обратите внимание, что подчеркивание означает “что угодно”. Мы выбрали эту задачу, потому что это один из примеров в SWISH Prolog (см блок Опробуйте), что означает, что нам не нужно перечислять здесь всё. Вы, вероятно, захотите взглянуть на него и попробовать решить самостоятельно. Надеюсь, вы будете впечатлены тем, как легко решить эту задачу в Prolog, и, конечно будете впечатлены. В конце концов, после удаления комментариев и пустых строк, код Prolog составляет всего 28 строк, в то время как для программы на языке Си++, которую мы нашли, эта цифра равна 166. О, и если вы хотите увидеть полную картину, то, что пример SWISH может отобразить в виде таблицы, взгляните на графическое представление.

Решение этой “загадки зебры” вручную, вероятно, потребует довольно много проб и ошибок. Но Prolog способен решить ее, используя всего 28 строк кода.

Хотя Prolog считается декларативным языком программирования, он также может быть использован в императивном способе. В большинстве случаев он используется для любых арифметических манипуляций, требующихся как часть более широкой декларативной программы Al, но вполне возможно писать полностью императивные программы на Prolog. Например, при поиске можно найти код Prolog для арифметических упражнений, таких как умножение матриц, хотя он не так интуитивно понятен, как в более традиционных языках. И хотя это действительно не самое лучшее применение Prolog, интересно посмотреть на типичный код Prolog для решения проблемы Ханойской башни, который вы легко найдете в Интернете. Это типичный пример Prolog, так как его решение, кажется, требует определенного уровня Al, но в действительности код, используемый для этой цели, гораздо более императивный, чем декларативный.

Итак, хотя мы, конечно, советуем вам углубиться в Prolog для повышения уровня своего образования в области программирования, помните о его сильных и слабых сторонах. И мы, конечно, не рекомендуем вам в ближайшее время отказываться от Python или C++ в пользу Prolog.

Рейтинг
( 2 оценки, среднее 3 из 5 )
Понравилась статья? Поделиться с друзьями:
MasCloud
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: