Пролог — это язык логического программирования , возникший в области искусственного интеллекта и компьютерной лингвистики . [1] [2] [3]
Пролог уходит своими корнями в логику первого порядка , формальную логику , и в отличие от многих других языков программирования , Пролог задуман прежде всего как декларативный язык программирования : программа представляет собой набор фактов и правил , которые определяют отношения . Вычисление инициируется запуском запроса к программе . [4]
Язык был разработан и реализован в Марселе, Франция, в 1972 году Аленом Кольмерауэром и Филиппом Русселем на основе процедурной интерпретации предложений Хорна , предложенной Робертом Ковальски в Эдинбургском университете . [5] [6] [7]
Пролог был одним из первых языков логического программирования [8] и сегодня остается самым популярным языком такого рода, доступно несколько бесплатных и коммерческих реализаций. Язык использовался для доказательства теорем , [9] экспертных систем , [10] переписывания терминов , [11] систем типов , [12] и автоматического планирования , [13] , а также для его первоначальной предполагаемой области использования, обработки естественного языка. . [14] [15]
Пролог — это полный по Тьюрингу язык программирования общего назначения, который хорошо подходит для приложений интеллектуальной обработки знаний.
В Прологе логика программы выражается в терминах отношений, и вычисления инициируются путем выполнения запроса по этим отношениям. Отношения и запросы строятся с использованием единственного типа данных Пролога — термина . [4] Отношения определяются пунктами . По запросу механизм Пролога пытается найти опровержение отрицательного запроса . Если отрицательный запрос может быть опровергнут, т. е. найдена реализация для всех свободных переменных, которая делает объединение предложений и одноэлементное множество, состоящее из отрицаемого запроса, ложным, из этого следует, что исходный запрос с примененным найденным экземпляром является логическое следствие программы. Это делает Пролог (и другие языки логического программирования) особенно полезными для баз данных, символьной математики и приложений синтаксического анализа языков. Поскольку Пролог допускает нечистые предикаты , проверка истинного значения некоторых специальных предикатов может иметь некоторый преднамеренный побочный эффект , например вывод значения на экран. По этой причине программисту разрешено использовать некоторое количество традиционного императивного программирования , когда логическая парадигма неудобна. Он имеет чисто логическое подмножество, называемое «чистым Прологом», а также ряд экстралогических особенностей.
Единственным типом данных Пролога является термин . Термины — это атомы , числа , переменные или составные термины . [примечание 1]
x
, red
, 'Taco'
, 'some atom'
и 'p(a)'
.person_friends(zelda,[tom,jim])
.Особые случаи сложных терминов:
[]
. Например, [1,2,3,4]
или [red,green,blue]
.double_quotes
. Например, "to be, or not to be"
. [16]Программы на Прологе описывают отношения, определяемые посредством предложений. Чистый Пролог ограничен предложениями Horn . Для определения программ Пролога используются два типа предложений Хорна: факты и правила. Правило имеет вид
Голова : - Тело .
и читается как «Голова верна, если Тело истинно». Тело правила состоит из вызовов предикатов, которые называются целями правила . Встроенный логический оператор (имеется в виду оператор,/2
арности 2 с именем ) обозначает конъюнкцию целей и обозначает дизъюнкцию . Союзы и дизъюнкции могут появляться только в теле, а не в начале правила.,
;/2
Предложения с пустым телом называются фактами . Пример факта:
человек ( Сократ ).
что эквивалентно правилу:
человек ( сократ ) :- правда .
Встроенный предикат true/0
всегда истинен.
Учитывая вышеизложенный факт, можно спросить:
Сократ человек?
?- человек ( Сократ ). Да
что такое люди?
?- человек ( Х ). Х = Сократ
Предложения с телом называются правилами . Пример правила:
смертный ( X ) :- человек ( X ).
Если мы добавим это правило и спросим, что такое смертные?
?- смертный ( X ). Х = Сократ
Предикат (или определение процедуры ) — это набор предложений, заголовки которых имеют одинаковое имя и арность . Мы используем обозначение имя/арность для обозначения предикатов. Логическая программа представляет собой набор предикатов. Например, следующая программа на Прологе, определяющая некоторые семейные отношения, имеет четыре предиката:
мать_ребёнка ( Труда , Салли ). отец_ребёнок ( Том , Салли ). отец_ребенка ( Том , Эрика ). отец_ребёнок ( Майк , Том ). родной брат ( X , Y ) : - родительский_ребенок ( Z , X ), родительский_ребенок ( Z , Y ). родитель_ребенок ( X , Y ) : — отец_ребенок ( X , Y ). родитель_ребенок ( X , Y ) : — мать_ребенок ( X , Y ).
Предикат father_child/2
состоит из трех предложений, каждое из которых является фактом, а предикат parent_child/2
состоит из двух предложений, оба из которых являются правилами.
Из-за реляционной природы многих встроенных предикатов их обычно можно использовать в нескольких направлениях. Например, length/2
может использоваться для определения длины списка ( length(List, L)
, заданный список List
) и для создания скелета списка заданной длины ( length(X, 5)
), а также для генерации как скелетов списков, так и их длин вместе ( length(X, L)
). Аналогично, append/3
может использоваться как для добавления двух списков ( append(ListA, ListB, X)
данные списки ListA
и ListB
), так и для разделения данного списка на части ( append(X, Y, List)
, заданный список List
). По этой причине для многих программ на Прологе достаточно сравнительно небольшого набора библиотечных предикатов.
В качестве языка общего назначения Пролог также предоставляет различные встроенные предикаты для выполнения рутинных действий, таких как ввод/вывод , использование графики и иное взаимодействие с операционной системой. Эти предикаты не имеют реляционного значения и полезны только для побочных эффектов, которые они оказывают на систему. Например, предикат write/1
отображает термин на экране.
Итерационные алгоритмы могут быть реализованы с помощью рекурсивных предикатов. [17]
Рассмотрим parent_child/2
предикат, определенный в программе семейных отношений выше. Следующая программа на Прологе определяет отношение предка :
предок ( X , Y ) : - родительский_ребенок ( X , Y ). предок ( X , Y ) :- родитель_ребенок ( X , Z ), предок ( Z , Y ).
Он выражает, что X является предком Y, если X является родителем Y или X является родителем предка Y. Он рекурсивен, поскольку определяется в терминах самого себя ( ancestor/2
в теле второго предложения есть вызов предиката). ).
Выполнение программы на Прологе инициируется сообщением пользователем единственной цели, называемой запросом. Логично, что движок Пролога пытается найти решение , опровергающее отрицательный запрос. Метод разрешения, используемый Прологом, называется разрешением SLD . Если отрицательный запрос можно опровергнуть, из этого следует, что запрос с соответствующими привязками переменных является логическим следствием программы. В этом случае пользователю сообщаются все сгенерированные привязки переменных, и считается, что запрос выполнен успешно. С функциональной точки зрения стратегию выполнения Пролога можно рассматривать как обобщение вызовов функций в других языках, единственное отличие состоит в том, что одному вызову может соответствовать несколько заголовков предложений. В этом случае система создает точку выбора, объединяет цель с заголовком предложения первой альтернативы и продолжает работу над целями этой первой альтернативы. Если какая-либо цель не удалась в ходе выполнения программы, все привязки переменных, которые были сделаны с момента создания самой последней точки выбора, отменяются, и выполнение продолжается со следующей альтернативой этой точки выбора. Эта стратегия выполнения называется хронологическим возвратом . Например, с учетом программы семейных отношений, определенной выше, следующий запрос будет оценен как true:
?- брат ( Салли , Эрика ). Да
Это получается следующим образом: изначально единственным совпадающим заголовком предложения для запроса sibling(sally, erica)
является первый, поэтому доказательство запроса эквивалентно доказательству тела этого предложения с соответствующими привязками переменных, то есть соединением (parent_child(Z,sally), parent_child(Z,erica))
. Следующая цель, которую необходимо доказать, — это крайняя левая цель этого соединения, т. е. parent_child(Z, sally)
. Этой цели соответствуют два заголовка статей. Система создает точку выбора и пробует первую альтернативу, тело которой равно father_child(Z, sally)
. Эту цель можно доказать, используя факт , поэтому генерируется father_child(tom, sally)
привязка , и следующей целью, которую необходимо доказать, является вторая часть приведенного выше союза: . Опять же, это можно доказать соответствующим фактом. Поскольку все цели могут быть доказаны, запрос завершается успешно. Поскольку запрос не содержал переменных, пользователю не сообщается ни о каких привязках. Запрос с переменными, например:Z = tom
parent_child(tom, erica)
?- отец_ребенок ( Отец , Ребенок ).
перечисляет все действительные ответы при возврате.
Обратите внимание, что с указанным выше кодом запрос ?- sibling(sally, sally).
также завершается успешно. При желании можно было бы добавить дополнительные цели для описания соответствующих ограничений.
Встроенный предикат Пролога \+/1
обеспечивает отрицание как отказ , что позволяет проводить немонотонные рассуждения. Цель \+ illegal(X)
в правиле
законно ( X ) :- \+ незаконно ( X ).
оценивается следующим образом: Пролог пытается доказать illegal(X)
. Если доказательство этой цели может быть найдено, первоначальная цель (т. е. \+ illegal(X)
) терпит неудачу. Если доказательств не найдено, первоначальная цель достигнута. Поэтому \+/1
префиксный оператор называется «недоказуемым» оператором, поскольку запрос ?- \+ Goal.
завершается успешно, если цель недоказуема. Этот вид отрицания является правильным , если его аргумент «основной» (т. е. не содержит переменных). Разумность теряется, если аргумент содержит переменные и процедура доказательства завершена. В частности, теперь запрос ?- legal(X).
нельзя использовать для перечисления всего, что разрешено.
В Прологе загрузка кода называется консультацией . Пролог можно использовать в интерактивном режиме, вводя запросы в приглашении Пролога ?-
. Если решения нет, Пролог пишет no
. Если решение существует, оно выводится на печать. Если существует несколько решений запроса, их можно запросить, введя точку с запятой ;
. Существуют рекомендации по хорошей практике программирования для повышения эффективности, читаемости и удобства обслуживания кода. [18]
Ниже приведены примеры программ, написанных на Прологе.
Пример базового запроса на нескольких популярных диалектах Пролога:
Это сравнение показывает, что приглашение («?-» vs «| ?-») и статус разрешения («истина» vs «да», «ложь» vs «нет») могут отличаться от одной реализации Пролога к другой.
Любое вычисление может быть выражено декларативно как последовательность переходов состояний. Например, оптимизирующий компилятор с тремя проходами оптимизации может быть реализован как связь между исходной программой и ее оптимизированной формой:
program_optimized ( Prog0 , Prog ) : - оптимизация_pass_1 ( Prog0 , Prog1 ), оптимизация_pass_2 ( Prog1 , Prog2 ), оптимизация_pass_3 ( Prog2 , Prog ).
или, что эквивалентно, используя обозначение DCG :
программа_оптимизированная --> оптимизация_пасс_1 , оптимизация_пасс_2 , оптимизация_пасс_3 .
Алгоритм быстрой сортировки, связывающий список с его отсортированной версией:
раздел ([], _ , [], []). раздел ([ X | Xs ], Pivot , Smalls , Bigs ) :- ( X @< Pivot -> Smalls = [ X | Rest ], раздел ( Xs , Pivot , Rest , Bigs ) ; Bigs = [ X | Rest ], раздел ( Xs , Pivot , Smalls , Rest ) ). быстрая сортировка ([]) --> []. быстрая сортировка ([ X | Xs ]) --> { раздел ( Xs , X , Меньше , Больше ) } , быстрая сортировка ( Меньше ), [ X ], быстрая сортировка ( Больше ).
Шаблон проектирования — это общее многократно используемое решение часто встречающейся проблемы при проектировании программного обеспечения . Некоторые шаблоны проектирования в Прологе представляют собой скелеты, методы, [19] [20] клише, [21] схемы программ, [22] схемы логического описания, [23] и программирование высшего порядка . [24]
Предикат более высокого порядка — это предикат, который принимает в качестве аргументов один или несколько других предикатов. Хотя поддержка программирования высшего порядка выводит Пролог за пределы области логики первого порядка, которая не допускает количественной оценки предикатов, [25] ISO Prolog теперь имеет некоторые встроенные предикаты высшего порядка, такие как call/1
, call/2
, call/3
, findall/3
, setof/3
и bagof/3
. [26] Более того, поскольку произвольные цели Пролога могут быть созданы и оценены во время выполнения, легко написать предикаты более высокого порядка, такие как , maplist/2
который применяет произвольный предикат к каждому члену данного списка, и sublist/3
, который фильтрует элементы, которые удовлетворяют заданный предикат, также допускающий каррирование . [24]
Чтобы преобразовать решения из временного представления (замены ответов при возврате) в пространственное представление (термины), Пролог имеет различные предикаты всех решений, которые собирают в список все замены ответов данного запроса. Это можно использовать для понимания списка . Например, совершенные числа равны сумме своих собственных делителей:
Perfect ( N ) :- между ( 1 , inf , N ), U равно N // 2 , findall ( D , ( между ( 1 , U , D ), N mod D =:= 0 ), Ds ), sumlist ( Дс , Н ).
Это можно использовать для перечисления совершенных чисел и для проверки того, является ли число совершенным.
Другой пример: предикат maplist
применяет предикат P
ко всем соответствующим позициям в паре списков:
список карт ( _ , [], []). список карт ( P , [ X | Xs ], [ Y | Ys ]) : - вызов ( P , X , Y ), список карт ( P , Xs , Ys ).
When P
— предикат, который для всех X
объединяется P(X,Y)
с Y
одним уникальным значением, maplist(P, Xs, Ys)
что эквивалентно применению функции карты в функциональном программировании как Ys = map(Function, Xs)
.
Стиль программирования высшего порядка на Прологе был впервые использован в HiLog и λProlog .
Для программирования в целом Пролог предоставляет систему модулей , соответствующую стандарту ISO. [27] Однако, хотя большинство систем Пролога поддерживают структурирование кода на модули, практически ни одна реализация не соответствует модульной части стандарта ISO. Вместо этого большинство систем Пролога решили поддерживать в качестве стандарта де-факто модульную систему Quintus / SICStus . Однако дополнительные предикаты удобства, касающиеся модулей, предоставляются только некоторыми реализациями и часто имеют небольшие различия в своей семантике. [28]
Некоторые системы решили реализовать концепцию модуля в виде компиляции из исходного кода в базовый ISO Prolog, как в случае с Logtalk . [29] GNU Prolog изначально отклонился от модулей ISO, выбрав вместо этого контекстно-логическое программирование, в котором загрузка и выгрузка модуля (модуля) может выполняться динамически. [30] Чао разработал строгую модульную систему, которая, будучи в основном совместимой со стандартом де-факто , используемым другими системами Пролога, поддается точному статическому анализу, поддерживает сокрытие терминов и облегчает программирование в целом. [31] XSB использует другой подход и предлагает модульную систему на основе атомов . [32] Последние две системы Пролога позволяют контролировать видимость терминов в дополнение к видимости предикатов. [33]
Существует специальная нотация, называемая грамматиками определенного предложения (DCG). Правило, определенное через -->/2
вместо, :-/2
расширяется препроцессором ( expand_term/2
возможностью, аналогичной макросам в других языках) в соответствии с несколькими простыми правилами переписывания, в результате чего получаются обычные предложения Пролога. В частности, переписывание снабжает предикат двумя дополнительными аргументами, которые можно использовать для неявного связывания состояния, [ необходимы пояснения ] аналогично монадам в других языках. DCG часто используются для написания анализаторов или генераторов списков, поскольку они также предоставляют удобный интерфейс для списков различий.
Пролог является гомоиконным языком и предоставляет множество возможностей для размышлений . Его стратегия неявного выполнения позволяет написать краткий метациклический вычислитель (также называемый метаинтерпретатором ) для чистого кода Пролога:
решить ( верно ). решить (( Подцель1 , Подцель2 )) :- решить ( Подцель1 ), решить ( Подцель2 ). решить ( Глава ) :- предложение ( Глава , Тело ), решить ( Тело ).
где true
представляет собой пустой союз и clause(Head, Body)
объединяется с предложениями в базе данных формы Head :- Body
.
Поскольку программы Пролога сами по себе представляют собой последовательности терминов Пролога ( :-/2
это инфиксный оператор ), которые легко читаются и проверяются с помощью встроенных механизмов (таких как read/1
), можно писать собственные интерпретаторы, которые дополняют Пролог функциями, специфичными для предметной области. Например, Стерлинг и Шапиро представляют метаинтерпретатор, который выполняет рассуждения с неопределенностью, воспроизведенный здесь с небольшими изменениями: [34] : 330
решить ( верно , 1 ) :- !. решить (( Подцель1 , Подцель2 ) , Определенность :- !, решить ( Подцель1 , Определенность1 ), решить ( Подцель2 , Определенность2 ) , Определенность минимальна ( Определенность1 , Определенность2 ). решить ( Цель , 1 ) :- встроенный ( Цель ), !, Цель . решить ( Глава , Уверенность ) :- section_cf ( Глава , Тело , Уверенность1 ), решить ( Тело , Уверенность2 ), Определенность есть Уверенность1 * Уверенность2 .
Этот интерпретатор использует таблицу встроенных предикатов Пролога вида [34] : 327.
встроенный ( A есть B ). встроенный ( читай ( X )). % и т. д.
и предложения, представленные как clause_cf(Head, Body, Certainty)
. Учитывая это, его можно назвать solve(Goal, Certainty)
выполнением Goal
и получением определенной уверенности в результате.
Чистый Пролог основан на подмножестве логики предикатов первого порядка , предложений Хорна , которая является полной по Тьюрингу . Полноту Пролога по Тьюрингу можно показать, используя его для моделирования машины Тьюринга:
Тьюринг ( Tape0 , Tape ) : - выполнить ( q0 , [], Ls , Tape0 , Rs ), перевернуть ( Ls , Ls1 ), добавить ( Ls1 , Rs , Tape ). выполнить ( qf , Ls , Ls , Rs , Rs ) :- !. выполнить ( Q0 , Ls0 , Ls , Rs0 , Rs ) : - символ ( Rs0 , Sym , RsRest ), один раз ( правило ( Q0 , Sym , Q1 , NewSym , Action )), действие ( Action , Ls0 , Ls1 , [ NewSym | RsRest ], Rs1 ), выполнить ( Q1 , Ls1 , Ls , Rs1 , Rs ). символ ([], b , []). символ ([ Sym | Rs ], Sym , Rs ). действие ( влево , Ls0 , Ls , Rs0 , Rs ) : - влево ( Ls0 , Ls , Rs0 , Rs ). действие ( остаться , Ls , Ls , Rs , Rs ). действие ( право , Ls0 , [ Sym | Ls0 ], [ Sym | Rs ], Rs ). влево ([], [], Rs0 , [ b | Rs0 ]). влево ([ L | Ls ], Ls , Rs , [ L | Rs ]).
Простой пример машины Тьюринга определяется фактами:
правило ( q0 , 1 , q0 , 1 , вправо ). правило ( q0 , b , qf , 1 , остаться ).
Эта машина выполняет приращение на одно число в унарном кодировании: она перебирает любое количество ячеек «1» и добавляет в конце дополнительную «1». Пример запроса и результата:
?- Тьюринга ([ 1 , 1 , 1 ], Ts ). Ц знак равно [ 1 , 1 , 1 , 1 ] ;
Это иллюстрирует, как любое вычисление может быть выражено декларативно как последовательность переходов состояний, реализованных в Прологе как отношение между последовательными интересующими состояниями.
Технический стандарт Prolog Международной организации по стандартизации (ISO) состоит из двух частей. ISO/IEC 13211-1, [26] [35], опубликованный в 1995 году, направлен на стандартизацию существующих практик многих реализаций основных элементов Пролога. Он прояснил аспекты языка, которые ранее были неоднозначными, и привел к созданию переносимых программ. Есть три исправления: Кор.1:2007, [36] Кор.2:2012, [37] и Кор.3:2017. [38] ISO/IEC 13211-2, [26], опубликованный в 2000 году, добавляет в стандарт поддержку модулей. Стандарт поддерживается рабочей группой ISO/IEC JTC1 / SC22 /WG17 [39] . ANSI X3J17 — это Техническая консультативная группа США по этому стандарту. [40]
Для повышения эффективности код Пролога обычно компилируется в абстрактный машинный код, на который часто влияет набор команд абстрактной машины Уоррена (WAM) на основе регистров. [41] Некоторые реализации используют абстрактную интерпретацию для получения информации о типе и режиме предикатов во время компиляции или компиляции в реальный машинный код для повышения производительности. [42] Разработка эффективных методов реализации кода Пролога является областью активных исследований в сообществе логического программирования, и в некоторых реализациях используются различные другие методы выполнения. К ним относятся бинаризация предложений и виртуальные машины на основе стека . [ нужна цитата ]
Системы Пролога обычно реализуют хорошо известный метод оптимизации, называемый оптимизацией хвостового вызова (TCO), для детерминированных предикатов, демонстрирующих хвостовую рекурсию или, в более общем плане, хвостовые вызовы: кадр стека предложения отбрасывается перед выполнением вызова в хвостовой позиции. Таким образом, детерминированные предикаты хвостовой рекурсии выполняются с постоянным пространством стека, как циклы в других языках.
Поиск предложений, которые можно объединить с термином в запросе, линеен по количеству предложений. Индексирование терминов использует структуру данных , которая обеспечивает поиск в сублинейном времени . [43] Индексирование влияет только на производительность программы, но не на семантику. Большинство Прологов используют индексацию только первого термина, поскольку индексирование всех терминов является дорогостоящим, но методы, основанные на словах, закодированных в полях , или наложенных кодовых словах , обеспечивают быструю индексацию по всему запросу и заголовку. [44] [45]
Некоторые системы Пролога, такие как WIN-PROLOG и SWI-Prolog, теперь реализуют хеширование, чтобы помочь более эффективно обрабатывать большие наборы данных. Это имеет тенденцию давать очень большой прирост производительности при работе с большими корпусами, такими как WordNet .
Некоторые системы Пролога ( B-Prolog , XSB , SWI-Prolog , YAP и Ciao ) реализуют метод запоминания , называемый табличным , который освобождает пользователя от необходимости вручную сохранять промежуточные результаты. Таблизация — это компромисс между пространством и временем ; время выполнения можно сократить, используя больше памяти для хранения промежуточных результатов: [46] [47]
Подцели, встречающиеся при оценке запроса, сохраняются в таблице вместе с ответами на эти подцели. Если подцель встречается повторно, при оценке повторно используется информация из таблицы, а не повторно выполняется разрешение пунктов программы. [48]
Таблицы можно расширять в различных направлениях. Он может поддерживать рекурсивные предикаты посредством разрешения SLG или линейного табличного представления. В многопоточной системе Пролога результаты табличного представления могут оставаться конфиденциальными для потока или совместно использоваться всеми потоками. А при поэтапном составлении таблиц составление таблиц может реагировать на изменения.
В ходе проекта «Компьютерные системы пятого поколения» предпринимались попытки реализовать Пролог на аппаратном уровне с целью добиться более быстрого выполнения с помощью специализированных архитектур. [49] [50] [51] Кроме того, Пролог имеет ряд свойств, которые могут обеспечить ускорение за счет параллельного выполнения. [52] Более поздний подход заключался в компиляции ограниченных программ на Прологе в программируемую вентильную матрицу . [53] Однако быстрый прогресс в аппаратном обеспечении общего назначения постоянно опережает более специализированные архитектуры.
Sega реализовала Prolog для использования с Sega AI Computer, выпущенным для японского рынка в 1986 году. Prolog использовался для чтения ввода на естественном языке на японском языке через сенсорную панель . [54]
Хотя Пролог широко используется в исследованиях и образовании, [55] Пролог и другие языки логического программирования не оказали существенного влияния на компьютерную индустрию в целом. [56] Большинство приложений невелики по промышленным стандартам, и лишь немногие из них превышают 100 000 строк кода. [56] [57] Программирование в целом считается сложным, поскольку не все компиляторы Пролога поддерживают модули, и существуют проблемы совместимости между системами модулей основных компиляторов Пролога. [29] Переносимость кода Пролога между реализациями также была проблемой, но события, произошедшие с 2007 года, означали: «переносимость внутри семейства реализаций Пролога, производных от Эдинбурга/Квинта, достаточно хороша, чтобы обеспечить поддержку переносимых реальных приложений». [58]
Программное обеспечение, разработанное на Прологе, подвергалось критике за высокие потери производительности по сравнению с традиционными языками программирования. В частности, стратегия недетерминированного вычисления Пролога может быть проблематичной при программировании детерминированных вычислений или даже при использовании «не заботящегося о недетерминизме» (когда делается единственный выбор вместо возврата ко всем возможностям). Для достижения желаемой производительности, возможно, придется использовать сокращения и другие языковые конструкции, разрушая одну из главных достопримечательностей Пролога - возможность запускать программы «назад и вперед». [59]
Пролог не является чисто декларативным: из-за таких конструкций, как оператор вырезания , для его понимания необходимо процедурное чтение программы Пролога. [60] Порядок предложений в программе на Прологе важен, поскольку от него зависит стратегия выполнения языка. [61] Другие языки логического программирования, такие как Datalog , действительно декларативны, но ограничивают язык. В результате многие практические программы на Прологе написаны в соответствии с порядком поиска в глубину Пролога , а не как чисто декларативные логические программы. [59]
На основе Пролога были разработаны различные реализации, расширяющие возможности логического программирования во многих направлениях. К ним относятся типы , режимы, логическое программирование с ограничениями (CLP), объектно-ориентированное логическое программирование (OOLP), параллелизм, линейная логика (LLP), возможности функционального логического программирования и логического программирования высшего порядка , а также совместимость с базами знаний :
Пролог — нетипизированный язык. Попытки представить и расширить Пролог типами начались в 1980-х годах [62] [63] и продолжаются с 2008 года [обновлять]. [64] Информация о типах полезна не только для обеспечения безопасности типов , но и для рассуждений о программах на Прологе. [65]
Синтаксис Пролога не определяет, какие аргументы предиката являются входными, а какие выходными. [66] Однако эта информация важна, и ее рекомендуется включить в комментарии. [67] Режимы предоставляют ценную информацию при обсуждении программ на Прологе [65] , а также могут использоваться для ускорения выполнения. [68]
Программирование логики ограничений расширяет Пролог, включив в него концепции удовлетворения ограничений . [69] [70] Программа логики ограничений допускает ограничения в теле предложений, например: A(X,Y) :- X+Y>0.
Она подходит для крупномасштабных задач комбинаторной оптимизации [71] и, таким образом, полезна для промышленных приложений, таких как автоматическое составление расписаний. и планирование производства . Большинство систем Пролога поставляются по крайней мере с одним решателем ограничений для конечных областей, а часто также с решателями для других областей, таких как рациональные числа .
Flora-2 — это объектно-ориентированная система представления знаний и рассуждений, основанная на F-логике и включающая в себя HiLog , транзакционную логику и отменяемое рассуждение .
Logtalk — это объектно-ориентированный язык логического программирования, который может использовать большинство реализаций Пролога в качестве внутреннего компилятора. Будучи мультипарадигмальным языком, он включает поддержку как прототипов, так и классов.
Oblog — это небольшое портативное объектно-ориентированное расширение Пролога, созданное Маргарет МакДугалл из EdCAAD, Эдинбургский университет.
Objlog — это фреймовый язык, сочетающий объекты и Prolog II от CNRS, Марсель, Франция.
Prolog++ был разработан компанией Logic Programming Associates и впервые выпущен в 1989 году для ПК с MS-DOS. Была добавлена поддержка других платформ, и в 1995 году была выпущена вторая версия. Книга Криса Мосса о Прологе++ была опубликована издательством Addison-Wesley в 1994 году.
Visual Prolog — это мультипарадигмальный язык с интерфейсами, классами, реализациями и объектными выражениями.
Системы Пролога, предоставляющие графическую библиотеку, — это SWI-Prolog , [72] Visual Prolog , WIN-PROLOG и B-Prolog .
Prolog-MPI — это расширение SWI-Prolog с открытым исходным кодом для распределенных вычислений через интерфейс передачи сообщений . [73] Также существуют различные параллельные языки программирования Пролог. [74]
Некоторые реализации Пролога, особенно Visual Prolog , SWI-Prolog и Ciao , поддерживают веб-программирование на стороне сервера с поддержкой веб-протоколов HTML и XML . [75] Существуют также расширения для поддержки форматов семантической сети , такие как Resource Description Framework (RDF) и Web Ontology Language (OWL). [76] [77] Пролог также предлагался в качестве клиентского языка. [78] Кроме того, Visual Prolog поддерживает JSON-RPC и Websockets .
Cedar. Архивировано 19 октября 2010 г. на Wayback Machine . Это бесплатный базовый интерпретатор Пролога. Начиная с версии 4 и выше, Cedar имеет поддержку FCA (Flash Cedar App). Это обеспечивает новую платформу для программирования на Прологе с помощью ActionScript .
Существуют фреймворки, которые могут служить мостом между Прологом и другими языками:
Название Пролог было выбрано Филиппом Русселем по предложению жены как аббревиатура от programment en logique ( по-французски программирование в логике ). [79] Он был создан примерно в 1972 году Аленом Кольмерауэром и Филиппом Русселем на основе процедурной интерпретации Робертом Ковальским статей Хорна . Частично это было мотивировано желанием согласовать использование логики как декларативного языка представления знаний с процедурным представлением знаний, которое было популярно в Северной Америке в конце 1960-х и начале 1970-х годов. По словам Роберта Ковальски , первая система Пролога была разработана в 1972 году Колмерауэром и Филиппом Русселем. [5] Первой реализацией Пролога был интерпретатор, написанный на Фортране Жераром Баттани и Анри Мелони. Дэвид Х.Д. Уоррен взял этот интерпретатор в Эдинбургский университет и там реализовал альтернативный интерфейс, который стал определять синтаксис «Эдинбургского Пролога», используемый в большинстве современных реализаций. Уоррен также реализовал первый компилятор для Пролога, создав влиятельный Пролог DEC-10 в сотрудничестве с Фернандо Перейрой. Позже Уоррен обобщил идеи, лежащие в основе Пролога DEC-10, и создал Абстрактную машину Уоррена .
Европейские исследователи ИИ отдавали предпочтение Прологу, а американцы — Лиспу , что, как сообщается, вызвало множество националистических дебатов о достоинствах языков. [80] Большая часть современного развития Пролога возникла благодаря проекту « Компьютерные системы пятого поколения» (FGCS), который разработал вариант Пролога под названием «Kernel Language» для своей первой операционной системы .
Первоначально чистый Пролог был ограничен использованием средства доказательства резолюционной теоремы с предложениями Хорна вида:
Ч:- Б 1 , ..., Б н .
Применение средства доказательства теорем рассматривает такие предложения как процедуры:
чтобы показать/решить H, показать/решить B 1 и ... и B n .
Однако вскоре чистый Пролог был расширен, включив в него отрицание как неудачу , в которой отрицательные условия формы not(B i ) проявляются в попытке и неудаче решить соответствующие положительные условия B i .
Последующие расширения Пролога, созданные первоначальной командой, добавили в реализации возможности программирования логики ограничений .
Пролог использовался в Watson . Watson использует программное обеспечение IBM DeepQA и платформу Apache UIMA (архитектура управления неструктурированной информацией). Система написана на различных языках, включая Java, C++ и Prolog, и работает под управлением операционной системы SUSE Linux Enterprise Server 11 с использованием инфраструктуры Apache Hadoop для обеспечения распределенных вычислений. Пролог используется для сопоставления с образцом деревьев синтаксического анализа естественного языка. Разработчики заявили: «Нам нужен был язык, на котором мы могли бы удобно выражать правила сопоставления с образцом для деревьев синтаксического анализа и других аннотаций (например, результатов распознавания именованных объектов), а также технология, которая могла бы очень эффективно выполнять эти правила. Мы обнаружили, что Пролог был идеальным выбором языка из-за его простоты и выразительности ». [15] Пролог используется в платформе разработки Low-Code GeneXus , ориентированной на искусственный интеллект. [ нужна цитация ] Графическая база данных TerminusDB с открытым исходным кодом реализована на Прологе. [81] TerminusDB предназначен для совместного построения и управления графами знаний .