"пролог" - язык программирования или основа искусственного интеллекта. Логическое программирование. Основы языка Пролог Где применяется prolog

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

Пролог - уникален. Это единственный язык представляющий парадигму декларативного программирования; это язык, который имеет сотни различных имплементаций, но они все равно называются Prolog, добавляя лишь префиксы и суффиксы к названию; это живой язык в котором не происходит никаких существенных изменений более 20 лет; это, наверное, единственный настолько популярный язык программирования, который не имеет применения в реальном программировании. Почему же Prolog?

Пролог - уникален по своей природе, он появился благодаря счастливому совпадению (таинственному устройству мира). Когда-то в 60-х годах очень бурно развивалась теория автоматического доказательства теорем и Робинсоном был предложен алгоритм резолюций, который позволял доказать любую верную теорему (вывести из аксиом) за конечное время (за какое не известно). Как оказалось позже, это наилучшее решение общей задачи, невозможно доказать теорему за ограниченное число операций. Простыми словами, алгоритм представляет собой обход (в общем случае бесконечного) графа в ширину, естественно, что предсказуемость работы алгоритма практически равно 0, соответственно для Языка Программирования - это абсолютно не подходит. И в этот момент Кальмэроу нашел блестящее сужение задачи, благодаря которому доказательство некоторых теорем выглядело как процедурное исполнение программы. Стоит отметить, что класс доказуемых теорем достаточно широк и очень хорошо применим для класса программируемых задач. Вот так в 1972 появился Prolog.

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


Главной чертой Prolog является то, что его можно легко читать, но очень тяжело писать, что принципиально отличается от всех mainstream языков, которые так и говорят писать стало еще легче еще один шаг и можно будет писать на планшете, перетягивая рабочие модули как друзей в Google+ , от этого все мы знаем очень сильно страдает само качество кода. Вроде бы каждая строчка понятна, но как система работает за гранью понимания даже для разработчиков, как говорится наиндусили. Мне кажется во всех книгах по обучению Prolog, делают одну и ту же ошибку, начиная рассказ о фактах, отношениях, запросах и у человека складывается отношение к языку как к Экспертной Системе или Базе Данных. Гораздо важнее научится правильно читать программы и почитать так с десяток:)

Как правильно читать программы на прологе

Читать программы очень просто, так как в языке очень мало специальных символов и ключевых слов и они легко переводятся на естественный язык. Главная ошибка программиста, что он хочет сразу представить как программа работает, а не прочитать, что программа описывает, поэтому мне кажется обучить незатуманенный мозг обычного человека, гораздо проще чем програмиста.
Понятия
В языке существует 2 понятия предикаты (условия) и объекты (они же переменные и термы). Предикаты выражают некоторое условие, например объект зеленый или число простое, естественно что условия имеют входные параметры. Например green_object(Object) , prime_number(Number) . Сколько в предикате параметров, такова и арность предиката. Объектами - являются термы, константы и переменные. Константы - это числа и строки, переменные - выражают неизвестный объект, возможно искомый, и обозначаются как строчки с большой буквы. Оставим пока термы и рассмотрим простейшую программу.
Программа
Программа - это набор правил, вида Если условие1 и условие2 и… то верно условие. Формально эти правила объединяются через И, но противоречие получить невозможно, так как в Прологе отсутствует логическое отрицание, а в связке То может присутствовать только один предикат (условие).

A:- B_1, B_2. % правило читается как: Если B_1 и B_2, то A
нечетное_простое(Число) :- простое(Число), нечетное(Число).
% Если "Число" - простое и нечетное, то "Число" - нечетное_простое

Как видно имя переменной имеет область видимости - это правило. Математически верно, правило звучит: для любой переменной - «Число», если оно простое и нечетное, то оно простое_нечетное. Аналогично, можно перефразировать так: Если существует «Число», что оно нечетное и простое, то оно нечетно_простое. Поэтому имя переменной очень важно! Если в левой части (до:-) заменить Число на Число2, то правило поменяет смысл: Для любого Число2 и Число, если Число - простое и нечетное, то Число2 - простое нечетное. Получается все числа простые_нечетные! Это самая распространенная ошибка в Прологе.

A:- B_1, B_2. % правило читается как: Если B_1 и B_2, то A нечетное_простое(Число) :- простое(Число), нечетное(Число). % Если "Число" - простое и нечетное, то "Число" - нечетное_простое

Пример - совершенные числа
совершенное_число(Ч) :- число(Ч), сумма_делителей_без_числа(Ч, СуммаДелителей), равно(СуммаДелителей, Ч). совершенное_число(1). равно(Объект, Объект). сумма_делителей_без_числа(1, 1). сумма_делителей_без_числа(Число, Сумма) :- число_предыдущее(Число, Предыдущее), сумма_делителей_числа_до_числа(Число, Сумма, Предыдущее). сумма_делителей_числа_до_числа(Число, 1, 1). сумма_делителей_числа_до_числа(Число, Сумма, Делитель) :- делится_на(Число, Делитель), число_предыдущее(Делитель, Предыдущее), сумма_делителей_числа_до_числа(Число, СуммаПред, Предыдущее), сложить(СуммаПред, Делитель, Сумма). сумма_делителей_числа_до_числа(Число, Сумма, Делитель) :- не_делится_на(Число, Делитель), число_предыдущее(Делитель, Предыдущее), сумма_делителей_числа_до_числа(Число, Сумма, Предыдущее).

Для начала формально прочитаем, что означают правила:

  1. Если «Ч» - число и для «Ч» и «СуммаДелителей» выполняется условие сумма_делителей_без_числа, проще говоря СуммаДелителей есть сумма делителей числа «Ч», и «Ч» равно «СуммаДелителей», то «Ч» совершенное число.
  2. 1 - совершенное число. Правила могут не иметь условий, в этом случае они называются фактами.
  3. Всякий объект «О» равен «О». В принципе существует, стандартный предикат "=", но можно вполне заменить на свой.
  4. Факт сумма_делителей_без_числа 1 равна 1.
  5. Если сумма делителей «Число» до предыдущего числа «Число» равна «Сумма», то это и есть сумма_делителей_без_числа. Таким образом выражается, сумма делителей X меньше либо равных Y, так как X делится на X, поэтому берем Y = X - 1.
  6. Далее 3 предиката определяют сумму делителей число меньше либо равных Y (Делитель), 1-й случай Y равное 1, 2-й случай Число делится на Y, тогда сумма_делителей(X, Y) = сумма_делителей(X, Y-1) + Y, и 3-й случай Число не делится на Y, тогда сумма_делителей(X, Y) = сумма_делителей(X, Y-1).
Программа - как набор определений
Существует второй способ прочтения данных правил, менее математический и более естественный, основанный на «определениях». Можно заметить, что в Прологе все правила слева (в части то) содержат только одно условие, что по сути является «определением» это условия.
Например, 1-ое правило определение совершенных чисел. «Ч» совершенное число, когда «Ч» число и сумма делителей «Ч» равна «Ч». Одинаковые предикаты группируются по имени объединяясь условием «или». То есть к определению можно добавить: «Ч» совершенное число, когда.., или когда «Ч» - это 1.

Данный способ чтения широко применяется, так как позволяет объединять предикаты в однородные группы и помогает понять, в каком же порядке интерпретатор раскручивает предикаты, для того, чтобы
проверить истинность некоторого утверждения. Например, очевидно, что если предикат не имеет ни одного определения, то доказать истинность утверждения с ним невозможно. В примере № 1 не имеет определения предикат «делится_на».

Интересный факт, что в Прологе нет ни циклов, ни присвоения переменных, ни объявления типов, а если вспомнить еще про термы и отсечение, то язык становится алгоритмически полным.

Термы
Термы имеют рекурсивное определение, как именованная совокупность объектов. Терм = "имя"(объект, объект, ...), пример person("Name", "Surname"), "+"(1, 2), person(address("Некоторый адрес"), surname("Фамилия"), phone("Телефон")) . Если рассматривать терм, как математическое понятие, то терм является функцией, а точнее функтором, то есть "+"(1, 2) - означает, что существует такой объект, который равен 1+2. Это абсолютно не означает, что 1+2 = 3, в Прологе - это выражение неистинно, точно так же как и в группе остатков по модулю 2, там 3 вообще не существует. Опять же с математической точки зрения Переменные связываются словом Для Всех, а если в утверждении необходимо слово существует то, для этой цели применяется терм (функтор). Для любого числа существует число-факториал:- factorial(X, fact(X)).

С точки зрения программирования терм можно объяснить гораздо проще: терм - это объект с набором атрибутов, атрибуты могут быть другими термами или константами или переменными (то есть не определены). Главное отличие, все объекты в Prolog immutable, то есть менять атрибуты в них нельзя, зато есть специальное состояние - переменная.

Пример - целочисленная арифметика
нат(0). нат(число(Число)) :- нат(Число). плюс(0, Число, Число). плюс(число(Ч1), Ч2, число(Рез)) :- плюс(Ч1, Ч2, Рез). умножить(0, Число, 0). умножить(число(Ч1), Ч2, Рез2) :- умножить(Ч1, Ч2, Рез), плюс(Рез, Ч2, Рез2).
  1. Определение свойства нат (натуральное число). 0 - натуральное число, если Число натуральное, то существует объект число(Число), которое тоже является натуральным. Математически терм «число» выражает функцию +1, с точки зрения программирования «число» рекурсивная структура данных, вот ее элементы: число(0), число(число(0)), число(число(число(0))).
  2. Отношение плюс - 0 + Число = Число. Если Ч1 + Ч2 = Рез, то (Ч1+1) + Ч2 = (Рез+1).
  3. Отношение умножить - 0 * Число = 0. Если Ч1 * Ч2 = Рез и Рез + Ч2 = Рез2, то (Ч1+1) * Ч2 = Рез2.
Очевидно эти утверждения верны для обычной арифметики, но почему тогда мы не включили такие же очевидные как Число + 0 = Число. Ответ простой: избыточность очень плохо для любого определения. Да, это может помогать вычислениям, своеобразная преждевременная оптимизация, но побочными эффектами могут быть противоречия в определениях, неоднозначный вывод утверждения, зацикливание интерпретатора.

Как Prolog понимает предикаты и как доказывает утверждения

Конечно чтение программ, помогает ощутить стиль Пролог, но не делает понятным для чего и как данные определения могут использоваться. Полноценной программой, примеры приведенные выше, назвать нельзя так как не хватает входной точки. Входной точкой в Пролог является запрос, аналог запроса к базе данных SQL или аналог вызова главной функции в функциональном программировании. Примеры запросов: нат(Число) - найти натуральное число, плюс(0, 0, Результат) - найти результат сложения 0 и 0 в переменной Результат, нат(0) - проверить является ли 0 натуральным числом и др.

Конечно, результаты запросов не трудно предсказать из логических соображений, но крайне важно понять, как программа их получила. Все-таки Пролог не черный ящик, а язык программирования, и в отличие от базы данных, где строится SQL-план и запрос может выполняться по-разному на разных Базах данных, Пролог имеет вполне определенный порядок выполнения. Дело в том, что в Базе данных мы вполне знаем какой ответ мы хотим получить исходя из данных в таблице, к сожалению глядя на Пролог программы достаточно сложно сказать, какие утверждения логически выводимы, поэтому понять как работает Пролог интерпретатор гораздо проще.

Рассмотрим на примере запроса плюс(0, 0, Результат) :
1. Находим совпадение (своеобразный pattern-matching, резолюция) данного запроса с левой частью одно из правил. Для данного запроса плюс(0, Число, Число). Соотнесем поочередно все аргументы запроса с правилом и получим: 0 = 0, 0 = Число, Результат = Число. В этих уравнениях участвуют 2 переменные (Число и Результат), решив их мы получаем, что Число = Результат = 0. Так как у данного правила нет условий, мы получили ответ на заданный вопрос. Ответ: да и Результат = 0.

Запрос нат(Число) :
1. Находим 1-е совпадение с правилом, правило нат(0), решая уравнения по соответствию, проще говоря находя резолюцию, мы получаем Число = 0. Ответ: да и Число = 0.

Запрос плюс(Результат, 0, число(0)) :
1. Находим резолюцию с правилом плюс(0, Число, Число): Результат = 0, 0 = Число, число(0) = Число, но (!) Число = 0 = число(0) - не возможно так как 0 совпадает число(0). Следовательно ищем резолюцию со следующим правилом.
2. Находим резолюцию с правилом плюс(число(Ч1), Ч2, число(Рез)), получаем число(Ч1) = Результат, Ч2 = 0, число(Рез) = число(0), отсюда Рез = 0. У этого правила, есть условия которые мы должны проверить, учитывая результаты резолюции (значения переменных), плюс(Ч1, Ч2, Рез) -> плюс(Ч1, 0, 0). Запоминаем значение переменных в стеке и формируем новый запрос плюс(Ч1, 0, 0)
3*. Решая запрос плюс(Ч1, 0, 0) находим резолюцию с плюс(0, Число, Число) и получаем Ч1 = 0 и Число = 0.
4. Возвращаемся по стеку к предыдущим переменным Результат = число(Ч1) = число(0). Ответ найден число(0). Соответственно сейчас пролог машина решила уравнение X + 0 = 1.

Грамотное составление правил на языке Пролог, очень сложная штука, но если их составить компактно, то можно получать не только прямые ответы и решения, но и обратные.

Пример запроса плюс(Число, Число, Число) : ответ да, Число = 0.

Пример запроса плюс(0, 0, 0) : ответ нет, при первой же попытке все резолюции не выполняются.

Пример запроса плюс(Число, Число, число(Число)) : ответ да, Число = 1. Решение уравнения X + X = X + 1.

Попробуйте провести вывод для умножить(Число, число(0), число(0)), для этого потребуется 2 раза заносить в стек переменные и вычислять новый запрос. Суть Пролог машины такова, что вы можете отказаться от 1-го результата, тогда Пролог вернется к предыдущему состоянию и продолжит вычисление. Например запрос нат(Число) , сначала применит 1-е правило и выдаст 0, а затем применит 2-е правило + 1-е правило и выдаст число(0), можно повторить и получить бесконечную последовательность всех натуральных чисел. Другой пример, запрос плюс(Число, число(0), Число2) , будет выдавать последовательность всех пар решения уравнения X + 1 = Y.

Заключение

К сожалению, разумный размер топика, не дал мне подобраться к главной теме, а именно к решению сложных логических задач на языке Пролог, не обладая стратегией их решения. Большие куски кода на Прологе могут отпугнуть не только начинающих, но даже опытных программистов. Цель данной статьи показать, что программы на Прологе могут простым образом читаться на естественном языке , а также исполняться простейшим интерпретатором .
Главная особенность Пролога - это не черный ящик и не библиотека, который решает сложные логические задачи, в Mathematica можно ввести алгебраическое уравнение и она выдаст решение, но последовательность выполняемых шагов - неизвестна. Пролог не может решать общие логические задачи (у него отсутствует логическое «или» и «отрицание»), иначе бы его вывод был недетерминированный как линейной резолюции. Пролог - это золотая середина, между простым интерпретатором и машиной для доказательства теорем, сдвиг в любую сторон приводит к потери одного из свойств.

В следующей статье я бы хотел рассказать, как решаются задачи сортировки, о последовательности переливаний, Miss Manners и другие известные логические задачи. Для тех, кто почувствовал себя неудовлеторенным хочу предложить следующую задачу (решившему первым приз ):
Написать предикат , который бы генерировал, бесконечную последовательность натуральных чисел, начиная с 3. Это должны быть стандартные числа в Прологе, операции над которыми выполняются при помощи предиката is: X is 3 + 1 => X=4.

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

В октябре 1981 года Японское министерство международной торговли и промышленности объявило о создании исследовательской организации - Института по разработке методов создания компьютеров нового поколения (Institute for New Generation Computer Technology Research Center ). Целью данного проекта было создание систем обработки информации, базирующихся на знаниях. Предполагалось, что эти системы будут обеспечивать простоту управления за счет возможности общения с пользователями при помощи естественного языка. Эти системы должны были самообучаться, использовать накапливаемые в памяти знания для решения различного рода задач, предоставлять пользователям экспертные консультации, причем от пользователя не требовалось быть специалистом в информатике. Предполагалось, что человек сможет использовать ЭВМ пятого поколения так же легко, как любые бытовые электроприборы типа телевизора, магнитофона и пылесоса. Вскоре вслед за японским стартовали американский и европейский проекты.

Появление таких систем могло бы изменить технологии за счет использования баз знаний и экспертных систем. Основная суть качественного перехода к пятому поколению ЭВМ заключалась в переходе от обработки данных к обработке знаний. Японцы надеялись, что им удастся не подстраивать мышление человека под принципы функционирования компьютеров, а приблизить работу компьютера к тому, как мыслит человек, отойдя при этом от фон неймановской архитектуры компьютеров. В 1991 году предполагалось создать первый прототип компьютеров пятого поколения.

Теперь уже понятно, что поставленные цели в полной мере так и не были достигнуты, однако этот проект послужил импульсом к развитию нового витка исследований в области искусственного интеллекта и вызвал взрыв интереса к логическому программированию. Так как для эффективной реализации традиционная фон неймановская архитектура не подходила, были созданы специализированные компьютеры логического программирования PSI и PIM .

В качестве основной методологии разработки программных средств для проекта ЭВМ пятого поколения было избрано логическое программирование , ярким представителем которого является язык Пролог . Думается, что и в настоящее время Пролог остается наиболее популярным языком искусственного интеллекта в Японии и Европе (в США, традиционно, более распространен другой язык искусственного интеллекта -язык функционального программирования Лисп ).

Название языка "Пролог" происходит от слов ЛОГическое ПРОграммирование (PROgrammation en LOGique во французском варианте и PROgramming in LOGic - в английском).

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

В истории возникновения и развития языка Пролог можно выделить следующие этапы.

В 1965 году в работе "A machine oriented logic based on the resolution principle", опубликованной в 12 номере журнала " Journal of the ACM ", Дж Робинсон представил метод автоматического поиска доказательства теорем в исчислении предикатов первого порядка, получивший название " принцип резолюции ". Эту работу можно прочитать в переводе: Робинсон Дж. Машинно-ориентированная логика, основанная на принципе резолюции // Кибернетический сборник. - Вып. 7 (1970). На самом деле, идея данного метода была предложена Эрбраном в 1931 году, когда еще не было компьютеров (Herbrand, "Une methode de demonstration ", These, Paris, 1931). Робинсон модифицировал этот метод так, что он стал пригоден для автоматического, компьютерного использования, и, кроме того, разработал эффективный алгоритм унификации, составляющий базис его метода.

В 1973 году " группа искусственного интеллекта" во главе с Аланом Колмероэ создала в Марсельском университете программу, предназначенную для доказательства теорем. Эта программа использовалась при построении систем обработки текстов на естественном языке. Программа доказательства теорем получила название Prolog (от Programmation en Logique). Она и послужила прообразом Пролога. Ходят легенды, что автором этого названия была жена Алана Колмероэ. Программа была написана на Фортране и работала довольно медленно.

Большое значение для развития логического программирования имела работа Роберта Ковальского " Логика предикатов как язык программирования " (Kowalski R. Predicate Logic as Programming Language . IFIP Congress, 1974), в которой он показал, что для того чтобы добиться эффективности, нужно ограничиться использованием множества хорновских дизъюнктов . Кстати, известно, что Ковальский и Колмероэ работали вместе в течение одного лета.

В 1976 г. Ковальский вместе с его коллегой Маартеном ван Эмденом предложил два подхода к прочтению текстов логических программ: процедурный и декларативный. Об этих подходах речь пойдет в третьей лекции.

В 1977 году в Эдинбурге Уоррен и Перейра создали очень эффективный компилятор языка Пролог для ЭВМ DEC–10, который послужил прототипом для многих последующих реализаций Пролога. Что интересно,

Лекция посвящена решению задач при помощи графа пространства состояний. Пространство состояний описывается в виде множества состояний – вершин графа, множества переходов от состояния к состоянию – дуг графа, множества начальных состояний и множества конечных состояний. Решение задачи представляется в виде пути на графе пространства состояний, соединяющего начальное состояние с конечным. Если пространство состояний задачи невелико, то будут находиться все оптимальные решения с помощью поиска в глубину. В задачах с большим пространством состояний будет вычисляться только одно оптимальное решение посредством поиска в ширину. К задачам применяются универсальные решатели. Состояния в разных задачах могут принадлежать различным доменам. Для запоминания наилучших среди найденных решений используется "изменяемая переменная" varM. Компилятор сам находит нужные типы. Версия Visual Prolog 7.5, еще не опубликована. Ее публикация планируется в 2014 году, но точная дата пока не известна. Сейчас всем доступна версия Visual Prolog 7.4.

Появление "Пролога" было обусловлено развитием логики, математики и программирования. Последнее сыграло самую существенную роль. Специалисты по логике и математике предприняли попытку поставить программирование на «правильный путь», но развитие информационных технологий показало совершенно другой результат.

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

Классическое программирование против логики

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

Этот факт всегда давал призрачное основание считать создание инструмента для принятия решений простым делом. С появлением "Пролога" казалось: вопрос искусственного интеллекта - дело техники, и человек разумный придумал три закона робототехники. Однако искусственный интеллект так и остался призраком, а три закона робототехники оказались из сказки - «сделай то, не знаю что».

Программирование в классическом значении этого слова (часто используют термины "процедурное", "императивное" или "функциональное") развивалось и успешно преодолело «смутные времена» 80-90-х годов, когда языков программирования было несчетное количество.

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

Нельзя сказать, что "Пролог" как язык программирования не развивался. Но он не достиг обозначенных целей. Сегодня можно не только сказать, но и обосновать: "Пролог" - это академический язык для:

  • целей обучения;
  • логики предикатов;
  • математики;
  • узкого применения.

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

Программирование на языке "Пролог" для искусственного интеллекта не состоялось: за более чем сорокалетнюю историю языка не было ни одного кардинально нового, актуального для общественного сознания события, свидетельствующего об обратном.

Объективная реальность такова: выживает не столько сильнейшее, сколько востребованное и актуальное.

"Пролог" - язык декларативного программирования

Иметь инструмент описания фактов и правил - хорошо, но какой смысл? Факты и правила прекрасно ложатся в обычную базу данных. Квалифицированный классический программист предоставляет интерактивный диалог для пользователя, и последний решает свои задачи.

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

Декларативное изложение фактов и правил на любой реализации языка программирования "Пролог" - это условность, попытка формализовать реальность в ее интеллектуальном состоянии. Обычное программирование не трогает интеллект. Классическое программирование устраивает позиция: описание и обработка данных. Здесь есть масса проблем, но есть множество блестящих и работающих решений.

"Пролог" как язык программирования - это факты:

  • мама (Мария, Наташа); - Мария - мама Наташи;
  • папа (Евгений, Марина); - Евгений - папа Марины.

Здесь сразу за бортом оказывается факт: «Мария» и «Марина» - разные имена. Ничего не мешает дописать факт:

  • папа (Евгений, Мария); - Евгений - папа Марии.

Эти описания дают жизнь правилам:

  • родитель (x, y) <- папа (x, y);
  • родитель (x, y) <- мама (x, y);

Но не позволяют сделать вывод, что папа - отец Марины, а Марина - мама Марии. Эта проблема решаемая, можно дописать еще одно правило, добавить еще один факт. Но сколько таких действий следует предпринять в реальной ситуации?

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

Семейство "Прологов"

Франция считается родиной "Пролога", а 1973 год - годом рождения. Интерес к языку периодически возобновлялся, но с завидной стабильностью затихал. Девиз языка: «Логика предикатов - это элементарно! Это способ объяснить, как работает мышление» - так и остался девизом.

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

Любое программирование - это данные и их обработка. Конструкции языка должны максимально точно описывать решаемую задачу, именно поэтому все известные реализации "Пролога": Turbo Prolog, Win Prolog, SWI Prolog, GNU Prolog, Visual Prolog и другие - содержат, помимо декларативных конструкций, обычные императивные выражения.

Считается, что семейство "Прологов" развивается в академических и научно-исследовательских организациях и поэтому как об общем языке можно говорить только в концептуальном смысле. Тем не менее сам факт, что концепция "Пролога" жива и развивается, можно считать: у этого языка есть область применения, и она востребована в определенном спектре задач.

Основа искусственного интеллекта

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

В конце 80-х годов был реальный, актуальный и востребованный интеллектуальный проект «Изобретающая машина». Была реальная попытка применить "Пролог" для формализации огромной практичной базы знаний (данных) по изобретениям, физическим, химическим и иным закономерностям.

Результат не был достигнут, слишком много фактов и правил нужно было написать на "Прологе" как языке программирования, которые носят банальный императивный характер. Между тем параллельно была реализована масса успешных программных продуктов на обычных языках.

В начале 90-х годов был успешно реализован проект реальной интеллектуальной системы, моделирующей поведение ребенка в возрасте до 3-лет на ЕС ЭВМ! Вариант использования "Пролога" даже не рассматривался.

Данная интеллектуальная система не только «соображала», что такое мама, папа, и чем отличается Мария от Марины, но и без особого напряжения самостоятельно перескочила с приобретенных знаний по этим вопросам к мячикам и их отличиям от кубиков, к цветам предметов и... (!) к элементарной математике: простые арифметические операции оказались ей по силам на основании знаний, приобретенных при решении совсем других задач.

Можно не утверждать, что классическое программирование опережает "Пролог" в части освоения территории искусственного интеллекта, но оно дает реальные результаты.

Что касается интеллекта как задачи - видимо, вопрос здесь лежит не в языке, а в идее реализации. Если ассемблер 1991 года смог «стать основой» для интеллектуальной системы ситуативного интеллекта, то вопрос явно лежит не в языке реализации, а в идее.

Язык программирования Prolog является одним из ведущих логических языков программирования. Он был создан Аленом Колмерье (Alain Colmerauer) в 1970-х годах. Это была попытка сделать язык программирования для начинающих, который дает возможность выразить логику, а не тщательно задавать инструкциями на экране компьютера то, что хочется получить.

Пролог используется во многих программах искусственного интеллекта, но его синтаксис и семантика очень простые и ясные (первоначальная цель заключалась в обеспечении инструментом для компьютерных неграмотных лингвистов). Название Пролог акроним для ПРОграммирования в ЛОГике и широко известен при обучении основам программирования.

Пролог основан на исчислении предикатов (точнее первого порядка исчисления предикатов), однако он ограничен формулами Хорна. Программы Пролога эффективны для доказательства теорем в первом приближении. Основные понятия объединения, хвостовая рекурсии и отслеживание.

Типы данных

Пролог не использует типы данных в том виде, который нам привычен в распространенных языках программирования. Мы можем говорить о Пролог лексических элементах вместо типов данных, что непривычно в программировании для чайников.

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

Большинство реализаций Prolog не делают различий между действительными и дробными числами.

Переменные

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

Так называемые анонимные переменные записываются в виде одного подчеркивание (_).

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

Список не является автономным типом данных, потому что он определяется рекурсивным построением (используя термин / 2 "."):

Atom - пустой список

Для удобства программиста, списки могут быть построены и разрушены в разному.

Если L является списком и X является элементом, то "." (X, L) является членом списка. Первый элемент X, за которым следует содержимое контекста L, синтаксически представляют как.

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

Элемент перечисление:
Предварение одного элемента:
Предварение несколько элементов:
Расширение термина: "."(abc, "."(1, "."(f(x), "."(Y, "."(g(A,rst), )))))

Строки обычно записывается как последовательность символов в кавычках. Они часто представлены в виде списков кодов символов таблицы ASCII.

Программирование на языке ПРОЛОГ сильно отличается от работы с процедурными языками. В Прологе Вы работаете с базами данных из фактов и правил, вы можете выполнять запросы к базе данных. Основной единицей Пролог является предикат, который определен, чтобы быть правдой (true). Предикат состоит из головы и числа аргументов. Например:

Здесь "cat" это голова, и "tom" является аргументом. Вот некоторые примеры запросов вы можете выполнить с помощью транслятора Пролог на основе этого факта:

Cat(tom).
yes.

Cat(X).
X = tom;
no.

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

Father(sally,pat).
father(pat,sally).

"father" в обоих случаях это голова, а "sally" и "pat"- аргументы. Однако в первом случае, Салли на первом месте в списке аргументов, а на втором Пэт на и наоборот. Первый случай является примером определения в порядке Глагол Предмет и Объект, ну а во втором примере порядок следующий Глагол Объект Предмет. Поскольку Пролог не понимает по-английски, обе версии прекрасно подходят, однако, считается хорошим стилем программирования придерживаться одного стиля, называемого соглашением, в ходе написания одной программы, чтобы потом не писать что-то вроде:

Father(pat,sally). father(jessica,james).

Некоторые предикаты встроены в язык, и позволяют Прологу уменьшить рутину повседневной деятельности (например, ввод / вывод с использованием графики и иного общения с операционной системой). Например, предикаты записи могут быть использованы для вывода на экран таким образом:

Write ("привет")

Будет отображать слово "Hello" на экране.

Правила

Второй тип заявлений в Пролог - это правила. Пример правила:

Light(on) :- switch(on).

": -" означает "если", это правило означает, light (on) верно (включен), если switch (on) это правда (иначе, если переключатель switch включен, тогда есть свет light). Правила могут также использовать переменные, переменные начинаются с большой буквы в то время как константы начинаются со строчных буквам. Например,

Father(X,Y) :- parent(X,Y),male(Y).

Это означает, "если кто-то является родителем, и он мужчина, то он является отцом". Причины и следствия могут находиться и в обратном порядке, так что это не противоречит обычной логике. Можно разместить несколько предикатов в разделе следствий, объединив их вместе, например:

Что эквивалентно нескольким объявлениям:

A:- d. b:- d. c:- d.

Но не разрешаются инструкции вида:

Что является эквивалентом "если с, то a или b". Это связано с ограничением, на накладываемым формулой Хорна.