LaurVas

Что я знаю о языке Пролог

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

Пролог — язык для фанатов рекурсии и головоломок. В нём нет циклов, но это не спасает от зацикливания (пример с лабиринтом ниже). В основе императивных языков лежит алгоритм, который можно описать блок-схемой или псевдокодом. В Прологе алгоритм не нужен, но это только на первый взгляд. Вам надо написать такой набор логических рассуждений (как правило рекурсивных), который при обработке интерпретатором превращается в алгоритм. Это одновременно баг и фича языка.

Говорят, что писать программы на Прологе намного сложнее, чем читать их. Так оно и есть, я проверил. Знакомство с этим языком я советую начать со статьи на хабре. Нет, правда, отличная статья!

Зачем это нужно?

Это эзотерический язык, не более. Поиск на гитхабе не выдаёт каких-либо значимых проектов. Пролог может быть интересен программистам, которые любят головоломки. Но я бы советовал не спешить, ведь есть более заманчивые языки: Haskel, Lisp или Ассемблер. Да и вообще не стоит забывать, что жизнь — это не только программирование :)

Есть узкий класс задач, для которых Пролог хорошо подходит. Например, с его помощью можно быстренько решить какую-нибудь логическую задачку (загадка Эйнштейна, поиск путей на графе, обход лабиринта и т.д.). Всё остальное проще запрогать на not(prolog). Потому что глупо представлять строчку текста в виде бинарного дерева.

У меня Пролог был в ВУЗе на курсе искусственного интеллекта. Студентам, которых заставляют изучать этот язык, я сочувствую. Писать программы сложно. Классика жанра — конкатенация двух списков, всего две строчки кода. Я не смог самостоятельно реализовать это за три часа. С другой стороны, когда долго над чем-то сидишь и наконец-то оно заработало… хочется улыбаться.

Пролог привлекает прежде всего своей необычностью. Думай рекурсивно, забудь про циклы!

Нам понадобится…

Насколько мне известно, самым популярным интерпретатором является SWI-Prolog. Еще встречаются GNU Prolog и Visual Prolog. Для установки под Windows идем на сайт проекта. Под линуксом достаточно установить пакет swi-prolog.

Писать программы можно в любом редакторе. Подсветка синтаксиса есть в Kate, Gedit, Medit, Sublime Text через плагин, наверняка Vim и Emacs. Редакторы ошибочно могут определять язык как Perl из-за расширения .pl.

Забавный пример

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

/* описываем конфигурацию лабиринта: */
door(1, 2). %существует дверь из первой во вторую комнаты
door(2, 3). %из второй в третью и т. д.
door(3, 4).
/* … */
door(1, 4).
door(X, Y):-door(Y, X). %если есть дверь из Y в X, то есть дверь из X в Y

Поначалу код работает так, как от него ожидается:

?- door(2, 3).
true
?- door(3, 2).
true

Но если спросить у интерпретатора о существовании прохода, которого на самом деле нет…

?- door(99, 100).

…то он ничего не сможет ответить, потому что войдет в ступор зациклится. Чтобы понять, почему так происходит, вводим команду trace. Она поможет отследить, что же на самом деле делает интерпретатор и почему так происходит. Очень помогает при написании программ, берите на заметку.

[trace] ?- door(99, 100).
    Call: (6) door(99, 100) ? creep
    Call: (7) door(100, 99) ? creep
    Call: (8) door(99, 100) ? creep
    Call: (9) door(100, 99) ? creep
    Call: (10) door(99, 100) ?

Что тут происходит? Не находя ответа в базе фактов, интерпретатор переходит к предикату door(X, Y):-door(Y, X). и пытается его удовлетворить новым проходом по базе фактов, затем снова цепляется за предикат, и т.д. Бесконечная рекурсия или зацикливание? Правильный ответ — рекурсия, ведь в Прологе нет циклов! Я так и не смог придумать как исправить предикат, чтобы он работал правильно.

Полезные ссылки

А ещё тут есть три разных оператора “равно”: =, =:=, is.