Loading AI tools
З Вікіпедії, вільної енциклопедії
Проло́г (фр. Prolog, англ. Prolog) — мова логічного програмування загального призначення, пов'язана зі штучним інтелектом та математичною лінгвістикою.[1][2][3]
Prolog | |
---|---|
Парадигма | логічне програмування |
Дата появи | 1972 |
Творці | Алан Кольмероеd, Роберт Ковальський і Філіп Руссельd |
Розробник | Алан Кольмерое[en] |
Основні реалізації | BProlog[en], Ciao[en], ECLiPSe[en], GNU Prolog[en], Jekejeke Prolog, Logic Programming Associates[en], Пролог Poplog[en], P#, Quintus, SICStus, Strawberry, SWI-Prolog, tuProlog, XSB, YAP-Prolog[en] |
Діалекти | Пролог ISO, Единбурзька Пролог |
Під впливом від | Planner |
Вплинула на | Visual Prolog[en], Mercury[en], Oz[en], Erlang, Strand[en], KL0[en], KL1[en], Datalog, CHR[en], XSB |
Звичайні розширення файлів | . |
Пролог має корені в логіці першого порядку, математичній логіці, та, на відміну від багатьох інших мов програмування, є декларативною: логіка програми виражається в термінах відношень, представлених як факти та правила. Обчислення ініціюється запуском запиту над цими відношеннями[4].
Цю мову програмування спочатку було задумано групою навколо Алана Кольмерое[en] в Марселі на початку 1970-х, а першу систему Пролог було розроблено в 1972-му Аланом Кольмерое та Філіпом Русселем[fr][5][6].
Пролог була однією з перших логічних мов програмування,[7] й залишається найпопулярнішою серед таких мов і на сьогодні, маючи декілька безкоштовних та комерційних реалізацій. Її застосовували як для доведення теорем,[8] експертних систем,[9] так і для її початкової області призначення, обробки природної мови.[10][11] Сучасні середовища Прологу підтримують як створення графічних інтерфейсів користувача, так і адміністративні або мережеві застосування.
Пролог добре підходить для розв'язання специфічних задач, що виграю́ть від логічних запитів на базі правил, таких як пошук базами даних, системи голосового керування та заповнення шаблонів.
Програмна логіка у Пролозі виражається в термінах відношень, а обчислення ініціюється запуском запиту над цими відношеннями. Відношення та запити створюються з використанням єдиного типу даних Прологу, терму.[4] Відношення виражаються твердженнями. Отримавши запит, рушій Прологу намагається знайти спростування резолюції заперечення запиту. Якщо заперечення запиту може бути спростовано, тобто, знайдено конкретизацію всіх вільних змінних, що робить об'єднання атомарних формул та множини-синґлетону, що складається із заперечення запиту, хибним, то з цього випливає, що початковий запит, із застосуванням знайденої конкретизації, є логічним висновком програми. Це робить Пролог (та інші логічні мови програмування) надзвичайно зручною для застосування в базах даних, символьній математиці та граматичному аналізі мов. Оскільки Пролог дозволяє нечисті предикати, перевірка істинності певних спеціальних предикатів може мати деякий навмисний побічний ефект, як-то виведення значення на екран. Через це програмістові дозволено певною мірою використовувати звичайне імперативне програмування, коли логічна парадигма є незручною. Пролог має як чисту логічну підмножину, що називається «чиста Пролог», так і ряд позалогічних властивостей.
Єдиним типом даних Прологу є терм. Терми можуть бути атомами, числами, змінними або складеними термами.
x
, синій
, 'Пиріжок'
та 'якийсь атом'
.рік_машини('Таврія', 1988)
та 'Друзі_Особи'(грай,[око,тур])
є прикладами складених термів.Особливі випадки складених термів:
[]
. Наприклад, [1,2,3]
, або [червоний,зелений,синій]
."бути чи не бути"
.Прологові програми описують відношення, визначені твердженнями. Чиста Пролог обмежена диз'юнктами Горна. Є два типи тверджень: факти та правила. Правило має вигляд
Голова :- Тіло.
і читається як «голова істинна, якщо тіло істинне». Тіло правила складається з викликів предикатів, що називаються цілями правила. Вбудований предикат ,/2
(що значить двоарний оператор з ім'ям ,
) позначає кон'юнкцію цілей, а ;/2
— диз'юнкцію. Кон'юнкції та диз'юнкції можуть бути присутні лише в тілі, але не в голові правила.
Твердження з порожніми тілами називаються фактами. Наприклад:
кіт(базиліо).
що рівноцінне правилу:
кіт(базиліо) :- true.
Вбудований предикат true/0
є завжди істинним.
Маючи наведений вище факт, можна спитати:
чи є базиліо котом?
?- кіт(базиліо).
Yes
що є котами?
?- кіт(X).
X = базиліо
Твердження з тілами називаються правилами. Наприклад:
тварина(X):- кіт(X).
Якщо ми додамо це правило та спитаємо, що є тваринами?
?- тварина(X).
X = базиліо
Оскільки природа багатьох вбудованих предикатів є відносною, їх зазвичай можна використовувати в кількох напрямках. Наприклад, 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
відображає терм на екрані.
Виконання прологової програми починається задаванням користувачем єдиної цілі, що зветься запитом. З точки зору логіки, рушій Прологу намагається знайти спростування резолюції заперечення цього запиту. Метод резолюції, що використовується у Пролозі, називається ВЛВ-резолюцією. Якщо заперечення запиту може бути спростовано, з цього випливає, що запит, з відповідними зв'язуваннями змінних, є логічним висновком програми. У такому разі всі створені зв'язування змінних повідомляються користувачеві, і про запит повідомляється, що він досяг успіху. З практичної точки зору, стратегію виконання Прологу можна уявити як узагальнення викликів функцій в інших мовах, з тією різницею, що заданому запитові можуть відповідати голови кількох тверджень. В такому випадку система створює точку вибору, об'єднує ціль з головою твердження першої альтернативи, і продовжує цілями цієї першої альтернативи. Якщо в напрямку виконання програми будь-яка ціль зазнає невдачі, всі зв'язування змінних, що було зроблено від останньої на той момент точки вибору, скасовуються, і виконання продовжується з наступною альтернативою цієї точки вибору. Ця стратегія виконання називається хронологічним пошуком з вертанням. Наприклад:
мати_дитини(ірина, святослав).
батько_дитини(ярослав, святослав).
батько_дитини(ярослав, анна).
батько_дитини(володимир, ярослав).
брат_або_сестра(X, Y) :- батько_або_мати_дитини(Z, X), батько_або_мати_дитини(Z, Y).
батько_або_мати_дитини(X, Y) :- батько_дитини(X, Y).
батько_або_мати_дитини(X, Y) :- мати_дитини(X, Y).
Виходячи з цього, наступний запит оцінюється як істинний:
?- брат_або_сестра(святослав, анна).
Yes
Це отримується таким чином: Спочатку єдиною відповідною головою твердження до запиту брат_або_сестра(святослав, анна)
є перша, тому надавання запиту є рівноцінним надаванню тіла того твердження з відповідними зв'язуваннями змінних, тобто, кон'юнкція (батько_або_мати_дитини(Z,святослав), батько_або_мати_дитини(Z,анна))
. Наступною ціллю для доведення є крайня зліва з цієї кон'юнкції, тобто, батько_або_мати_дитини(Z,святослав)
. Цій цілі відповідають голови двох правил. Система створює точку вибору, і пробує перший вибір, чиїм тілом є батько_дитини(Z, святослав)
. Цю ціль може бути доведено з використанням факту батько_дитини(ярослав, святослав)
, тому створюється зв'язування Z = ярослав
, і наступною ціллю для доведення стає друга частина наведеної вище кон'юнкції: батько_або_мати_дитини(ярослав, анна)
. І знову, це може бути доведено відповідним фактом. Оскільки всі цілі доведено, запит досягає успіху. Оскільки запит не містить жодних змінних, користувачеві не повідомляються жодні зв'язування. Запит зі змінними, як-то:
?- батько_дитини(Батько, Дитина).
перелічує всі дійсні відповіді пошуку з вертанням.
Зверніть увагу, що з наведеним вище кодом запит ?- брат_або_сестра(святослав, святослав).
також досягає успіху. Якщо потрібно, можна додати додаткові цілі для опису відповідних обмежень.
Ітеративні алгоритми може бути реалізовано засобами рекурсивних предикатів.
Вбудований предикат Прологу \+/1
забезпечує заперечення як відмову, що уможливлює немонотонну аргументацію. Ціль \+ нелегальне(X)
у правилі
легальне(X) :- \+ нелегальне(X).
обчислюється таким чином. Пролог намагається довести нелегальне(X)
. Якщо доведення цієї цілі знайдено, то початкова ціль (тобто, \+ нелегальне(X)
) зазнає невдачі. Якщо доведення не може бути знайдено, то початкова ціль досягає успіху. Отже, префіксний оператор \+/1
називається оператором «недовідне», оскільки запит ?- \+ Ціль.
досягає успіху, якщо Ціль не є довідною. Цей вид заперечення є правильним, якщо його аргумент є замкненим (тобто, не містить змінних). Правильність втрачається, якщо аргумент містить змінні, і процедура доведення є повною. Зокрема, запит ?- легальне(X).
тепер вже не може бути використано для перелічення усіх речей, що є легальними.
У Пролозі завантаження коду називається взяттям до уваги. Пролог може використовуватися інтерактивно шляхом введення запитів до підказки Прологу, ?-
. Якщо розв'язку не існує, то Пролог пише no
. Якщо розв'язок існує, то тоді друкується він. Якщо існує декілька розв'язків запиту, то їх може бути запитано введенням крапки з комою, ;
. Існують керівні принципи з належної практики програмування для покращення ефективності, читабельності та підтримуваності коду.[12]
Далі слідують деякі приклади програм, написаних мовою Пролог.
Приклад запиту:
?- write('Привіт, світе!'), nl.
Привіт, світе!
true.
?-
Будь-яке обчислення може бути виражено декларативно як послідовність переходу станів. Як приклад, оптимізувальний компілятор з трьома проходами оптимізації може бути реалізовано як відношення між початковою програмою та її оптимізованою формою:
програма_оптимізована(Прог0, Прог) :-
оптимізація_прохід_1(Прог0, Прог1),
оптимізація_прохід_2(Прог1, Прог2),
оптимізація_прохід_3(Прог2, Прог).
або рівнозначно з використанням запису граматики визначених тверджень:
програма_оптимізована --> оптимізація_прохід_1, оптимізація_прохід_2, оптимізація_прохід_3.
Алгоритм швидкого сортування, що ставить у відповідність спискові його відсортовану версію:
розділення([], _, [], []).
розділення([X|Xs], Опорне, Малі, Великі) :-
( X @< Опорне ->
Малі = [X|Решта],
розділення(Xs, Опорне, Решта, Великі)
; Великі = [X|Решта],
розділення(Xs, Опорне, Малі, Решта)
).
швидке_сортування([]) --> [].
швидке_сортування([X|Xs]) -->
{ розділення(Xs, X, Менші, Більші) },
швидке_сортування(Менші), [X], швидке_сортування(Більші).
Шаблон проектування це загальне рішення багаторазового використання поширеної проблеми у проектуванні програмного забезпечення. У Пролозі шаблони проектування можуть носити різні назви: кістяки та техніки,[13][14] кліше,[15] програмні схеми[16] та схеми опису логіки.[17] Альтернативою до шаблонів проектування є програмування вищих порядків.[18]
Детальніші відомості з цієї теми ви можете знайти в статті Логіка вищих порядків[en] та Програмування вищих порядків.
Предикат вищого порядку — це предикат, що має один або більше інших предикатів як аргументи. Хоча підтримка програмування вищих порядків і виводить Пролог з області логіки першого порядку, яка не дозволяє квантифікації предикатів,[19] Пролог ISO вже має деякі вбудовані предикати вищих порядків, такі як call/1
, call/2
, call/3
, findall/3
, setof/3
та bagof/3
.[20] Крім того, оскільки довільні цілі Прологу можуть створюватись та оцінюватись у реальному часі, нескладно писати предикати вищих порядків на кшталт maplist/2
, що застосовує довільний предикат до кожного елемента наданого списку, та sublist/3
, що відфільтровує елементи, які задовольняють наданому предикатові, уможливлюючи також і каррування.[18]
Для перетворення рішень з часового представлення (підстановки відповідей при зворотному пошуку) до просторового представлення (термів) Пролог має різноманітні предикати для всіх рішень, що збирають всі підстановки відповідей для заданого запиту до списку. Це може використовуватися у спискових виразах. Наприклад, досконалі числа дорівнюють сумі своїх дільників:
perfect(N) :-
between(1, inf, N), U is N // 2,
findall(D, (between(1,U,D), N mod D =:= 0), Ds),
sumlist(Ds, N).
Це може бути використано для перелічування досконалих чисел, а також для перевірки, чи є число досконалим.
Як інший приклад, предикат maplist
застосовує предикат P
до всіх відповідних положень у парі списків:
maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :-
call(P, X, Y),
maplist(P, Xs, Ys).
Коли P
є таким предикатом, що для кожного X
P(X,Y)
об'єднує Y
з єдиним унікальним значенням, maplist(P, Xs, Ys)
є еквівалентом застосування функції map у функційному програмуванні як Ys = map(Function, Xs)
.
Програмування вищих порядків було започатковано у Пролозі в HiLog[en] та λProlog[en].
Для великого програмування Пролог пропонує систему модулів. Цю систему модулів стандартизовано ISO.[21] Проте, не всі компілятори Прологу підтримують модулі, а також існують проблеми сумісності між системами модулів основних компіляторів Прологу.[22] Отже, модулі, написані під одним компілятором Прологу, не обов'язково працюватимуть під іншими.
Існує спеціальний запис, що називається граматиками визначених тверджень. Правило, визначене через -->/2
замість :-/2
, розкривається препроцесором (expand_term/2
, засіб, аналогічний макросам в інших мовах) відповідно до кількох прямих правил переписування, маючи результатом звичайні твердження Прологу. Найважливіше, що переписування споряджає предикат двома додатковими аргументами, що можуть використовуватися для неявного прокручування стану через них, аналогічно до монад в інших мовах. Граматики визначених тверджень часто використовуються для написання синтаксичних аналізаторів або генераторів списків, оскільки вони надають зручний інтерфейс до списків відмінностей.
Пролог є гомоіконною мовою, і забезпечує багато засобів для рефлексії. Її неявна стратегія виконання робить можливим написання стислого мета-циклічного інтерпретатора[en] (що також називають мета-інтерпретатором) коду чистої Пролог:
solve(true).
solve((Subgoal1,Subgoal2)) :-
solve(Subgoal1),
solve(Subgoal2).
solve(Head) :-
clause(Head, Body),
solve(Body).
де true
представляє порожню кон'юнкцію, а clause(Head, Body)
об'єднується з твердженнями бази даних вигляду Head :- Body
.
Оскільки прологові програми самі є послідовностями термів Прологу (:-/2
є інфіксним оператором), що легко читаються та аналізуються з використанням вбудованих механізмів (як-то read/1
), можливо писати спеціальні інтерпретатори, що розширюють Пролог предметно-орієнтованими властивостями. Наприклад, Стерлінг та Шапіро представляють мета-інтерпретатор, що виконує міркування з неточностями, відтворений тут із незначними видозмінами:[23]
solve(true, 1) :- !.
solve((Subgoal1,Subgoal2), Certainty) :-
!,
solve(Subgoal1, Certainty1),
solve(Subgoal2, Certainty2),
Certainty is min(Certainty1, Certainty2).
solve(Goal, 1) :-
builtin(Goal), !,
Goal.
solve(Head, Certainty) :-
clause_cf(Head, Body, Certainty1),
solve(Body, Certainty2),
Certainty is Certainty1 * Certainty2.
Цей інтерпретатор використовує таблицю вбудованих предикатів Пролог у вигляді[23]
builtin(A is B).
builtin(read(X)).
% etc.
та твердження, представлені як clause_cf(Голова, Тіло, Впевненість)
. Враховуючи це, його можна викликати як solve(Ціль, Впевненість)
, щоби виконати Ціль
та отримати міру впевненості в результаті.
Чиста Пролог базується на підмножині предикатної логіки першого порядку, диз'юнктах Горна, що є повною за Тюрингом. Повноту Прологу за Тюрингом може бути показано шляхом використання її для імітації машини Тюрінга:
turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
perform(qf, Ls, Ls, Rs, Rs) :- !.
perform(Q0, Ls0, Ls, Rs0, Rs) :-
symbol(Rs0, Sym, RsRest),
once(rule(Q0, Sym, Q1, NewSym, Action)),
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
perform(Q1, Ls1, Ls, Rs1, Rs).
symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).
action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).
action(stay, Ls, Ls, Rs, Rs).
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).
left([], [], Rs0, [b|Rs0]).
left([L|Ls], Ls, Rs, [L|Rs]).
Простий приклад машини Тюринга визначається фактами:
rule(q0, 1, q0, 1, right).
rule(q0, b, qf, 1, stay).
Ця машина виконує збільшення на одиницю числа в унарному кодуванні: вона проходить будь-яке число комірок «1» та додає додаткову «1» у кінці. Приклад запиту та результату:
?- turing([1,1,1], Ts).
Ts = [1, 1, 1, 1] ;
Це показує, як будь-яке обчислення може бути представлено декларативно як послідовність переходів станів, реалізовану в Пролозі як відношення між послідовними станами, що нас цікавлять.
Детальніші відомості з цієї теми ви можете знайти в статті Порівняння реалізацій Прологу[en].
Стандарт Прологу ISO складається з двох частин. ISO/IEC 13211-1,[20][24] опублікована в 1995 році, намагається стандартизувати наявні застосування багатьох реалізацій ключових елементів Прологу. Вона прояснила аспекти цієї мови, що раніше були неоднозначними, і веде до переносності програм. Є дві еррати: Cor.1:2007[25] та Cor.2:2012.[26] ISO/IEC 13211-2,[20] опублікована в 2000 році, додає до стандарту підтримку модулів. Стандарт підтримується робочою групою ISO/IEC JTC1[en]/SC22[en]/WG17[27]. Технічною дорадчою групою США для цього стандарту є ANSI X3J17.[28]
Для більшої ефективності код Прологу зазвичай компілюється в код абстрактної машини, що часто знаходиться під впливом набору інструкцій базованої на регістрах абстрактної машини Воррена[en].[29] Деякі реалізації вживають абстрактну інтерпретацію[en] для встановлення інформації про тип та напрямок предикатів під час компіляції, або, для вищої продуктивності, компілюють у код реальної машини.[30] У спільноті логічного програмування придумування ефективних методів реалізації коду Прологу є полем активних досліджень, і в деяких реалізаціях застосовується багато інших методів виконання. Вони включають перетворення тверджень у двійкову форму та віртуальні машини, базовані на стеку[en].[джерело?]
Для детермінованих предикатів, що демонструють хвостову рекурсію, або, загальніше, хвостові виклики, прологові системи зазвичай реалізують добре відомий метод оптимізації, що зветься оптимізацією хвостового виклику (англ. Tail Call Optimization, TCO): Перед виконанням виклику в хвостовій позиції кадр стеку твердження скасовується. Отже, детерміновані предикати з хвостовою рекурсією виконуються з незмінним простором стеку, як цикли в інших мовах.
Детальніші відомості з цієї теми ви можете знайти в статті Індексування термів[en].
Пошук тверджень, що є об'єднуваними із термом у запиті, є лінійним відносно кількості тверджень. Індексування термів[en] використовує структуру даних, що уможливлює суб-лінійний пошук.[31] Індексування впливає лише на продуктивність програми, семантики воно не зачіпає. Більшість Прологів використовує індексування лише за першим термом, оскільки індексування за всіма термами є витратним, але прийоми на базі кодованих полями слів або наднакладених[en] кодових слів забезпечують швидке індексування по всьому запитові та голові.[32][33]
Деякі прологові системи (BProlog[en], XSB, Yap, B-Prolog та Ciao) реалізують метод мемоізації, що зветься табулювання, що звільняє користувача від необхідності зберігати проміжні результати вручну.[34][35]
![]() |
Підцілі, що зустрічаються під час виконання запиту, зберігаються в таблиці, разом із відповідями на ці підцілі. Якщо підціль зустрічається знову, то виконання використовує інформацію з таблиці, замість повторного виконання міркування над реченнями програми.[36]
Оригінальний текст (англ.) Subgoals encountered in a query evaluation are maintained in a table, along with answers to these subgoals. If a subgoal is re-encountered, the evaluation reuses information from the table rather than re-performing resolution against program clauses. |
![]() |
Табулювання є просторово-часовим компромісом, тривалість виконання може бути зменшено за рахунок використання більшої кількості пам'яті для зберігання проміжних результатів.
Під час розробки проекту комп’ютерних систем п’ятої генерації були спроби реалізувати Пролог в апаратному вигляді з метою отримання швидшого виконання спеціальними архітектурами.[37][38][39] До того ж, Пролог має ряд властивостей, що можуть дозволити прискорення шляхом паралельного виконання.[40] Новішими підходами було компілювати обмежені прологові програми у програмовані користувачем вентильні матриці.[41] Однак, швидкий розвиток апаратного забезпечення загального призначення послідовно випередив спеціалізованіші архітектури.
Хоча Пролог широко застосовується в дослідницькій роботі та освіті, вона та інші логічні мови програмування не справили істотного впливу на комп'ютерну промисловість у цілому.[42] Більшість застосунків є малими за промисловими стандартами, лише деякі з них мають понад 100,000 рядків коду.[42][43] Велике програмування вважається складним, оскільки не всі компілятори Прологу підтримують модулі, а також існують проблеми сумісності між системами модулів основних прологових компіляторів.[22] Переносність коду Прологу між реалізаціями також була проблемою, але розробка після 2007 року означала: «переносність всередині сімейства реалізацій Прологу, що походять від Единбурзької Пролог або Quintus, є достатньо гарною для підтримки реальних переносних програм».[44]
Програмне забезпечення, розроблене на Пролозі, критикувалося за високі втрати продуктивності у порівнянні зі звичайними мовами програмування. Зокрема, прологова недетерміністська стратегія виконання може бути проблематичною при програмуванні детерміністських обчислень, або навіть при використанні «незважання на недетермінізм» (коли робиться єдиний вибір замість зворотнього пошуку всіма можливими). Для досягнення бажаної продуктивності може доводитися застосовувати відсікання та інші мовні конструкції, руйнуючи одну з головних принад Прологу, здатність виконувати програми «назад і вперед».[45]
Пролог не є чисто декларативною: оскільки вона має конструкції на кшталт оператора відсікання, для її розуміння потрібне також і процедурне прочитання написаних нею програм.[46] Порядок тверджень у прологовій програмі є суттєвим, оскільки стратегія виконання цієї мови залежить від нього.[47] Інші логічні мови програмування, такі як Datalog, є чисто декларативними, але це обмежує мову. В результаті багато практичних прологових програм написано так, щоби вони відповідали прологовому пошуку в глибину, а не як чисто декларативні логічні програми.[45]
З Прологу було розвинуто різноманітні реалізації для розширення можливостей логічного програмування у численних напрямках. Вони включають типи, режими, логічне програмування з обмеженнями[en] (англ. CLP), об'єктно-орієнтоване логічне програмування (англ. OOLP), паралелізм, лінійну логіку[en], можливості функційного програмування та програмування логіки вищих порядків[en], плюс функціональну сумісність з базами знань:
Пролог є нетипізованою мовою. Спроби запровадити типи сходять до 1980-х років,[48][49] і станом на 2008 рік все ще існують спроби розширити Пролог типами.[50] Ця інформація корисна не лише для безпечної типізації, а й для розуміння прологових програм.[51]
Ознака режиму | Інтерпретація |
---|---|
+ |
nonvar на вході |
- |
var на вході |
? |
Не визначено |
Синтаксис Прологу не визначає, які з аргументів предикату є вхідними, а які вихідними.[52] Проте ця інформація є істотною, і рекомендується включати її до коментарів.[53] Режими надають цінну інформацію для розуміння прологових програм,[51] а також можуть використовуватися для прискорення виконання.[54]
Логічне програмування з обмеженнями[en] розширює Пролог включенням концепцій із задоволення обмежень[en].[55][56] Програма з логікою обмежень дозволяє обмеження в тілах тверджень, як, наприклад, A(X,Y) :- X+Y>0.
Це підходить для великомасштабних задач комбінаторної оптимізації[57] й, отже, для застосувань у промислових умовах, таких як автоматизоване складання розкладів та планування виробництва[en]. Більшість прологових систем постачаються із щонайменше одним розв'язувачем обмежень для зліченних областей визначення, а часто також і з розв'язувачами для інших областей визначення, таких як дійсні числа.
Flora-2[en] є об'єктно-орієнтованим представленням знань та системою міркувань на базі F-logic[en], і включає HiLog[en], транзакційну логіку[en] та міркування методом виключення[en].
Logtalk[en] — це об'єктно-орієнтована мова логічного програмування, що може застосовувати більшість реалізацій Прологу як внутрішній компілятор. Як мультипарадигмова мова, вона включає підтримку як прототипів, так і класів.
Oblog — це невелике переносне об'єктно-орієнтоване розширення Прологу від Маргарити Макдугалл (англ. Margaret McDougall) з EdCAAD Единбурзького університету.
Objlog[en] була фреймовою мовою, що поєднувала об'єкти та Пролог II від НЦНД Франції у Марселі.
Prolog++[en] було розроблено компанією Logic Programming Associates[en], і вперше випущено у 1989 році для ПК MS-DOS. Було додано підтримку для інших платформ, і 1995 року випущено другу версію. У 1994 році видавництвом Addison-Wesley було опубліковано книгу Кріса Мосса (англ. Chris Moss) про Prolog++.
Прологовими системами, що пропонують графічну бібліотеку, є SWI-prolog,[58] Visual-prolog, LPA Prolog для Windows та B-Prolog.
Prolog-MPI є розширенням SWI-Prolog з відкритим кодом для розподілених обчислень через інтерфейс передачі повідомлень (англ. MPI).[59] Також існує декілька конкурентних мов програмування Пролог.[60]
Деякі реалізації Прологу, особливо SWI-Prolog та Ciao, підтримують вебпрограмування на серверному боці з підтримкою вебпротоколів, HTML та XML.[61] Існують також розширення для підтримки форматів семантичної павутини, таких як RDF та OWL.[62][63] Пролог також пропонувалася як мова клієнтського боку.[64]
Cedar є безкоштовним та елементарним інтерпретатором Прологу. Від версії 4 та вище Cedar має підтримку FCA (Flash Cedar App). Це забезпечує нову платформу для програмування Прологом через ActionScript.
Існують каркаси для сполучення між Прологом та іншими мовами:
Назву Пролог (фр. Prolog) було обрано Філіпом Русселем[fr] як абревіатуру від програмування в логіці (фр. programmation en logique). Пролог було створено в 1972 році Аланом Кольмерое[en] з Філіпом Русселем на основі процедурної інтерпретації диз'юнктів Горна Роберта Ковальського. Це було частково мотивоване бажанням примирити використання логіки як мови декларативного представлення знань з процедурним представленням знань, що було популярне в Північній Америці наприкінці 1960-х і на початку 1970-х років. Згідно Роберта Ковальського, першу прологову систему було розроблено в 1972 році Аланом Кольмерое та Філіпом Русселем.[5] Перші реалізації Прологу були інтерпретаторами. Однак, Девід Воррен[en] створив абстрактну машину Воррена[en], ранній та впливовий компілятор Прологу, що прийшов, щоби визначити «Единбурзький» діалект Прологу, що послужив основою синтаксису більшості сучасних реалізацій.
Європейські дослідники штучного інтелекту віддавали перевагу Прологу, тоді як американці віддавали перевагу Ліспу, що, як повідомлялося, призводило до численних націоналістичних дебатів про переваги цих мов.[65] Більшість сучасних розробок Прологу пішли від поштовху проекту комп’ютерних систем п’ятої генерації, в рамках якого було розроблено варіант Прологу під назвою Kernel Language[en] для його першої операційної системи.
Чисту Пролог було спочатку обмежено використанням системи доведення теорем з диз'юнктами Горна форми:
Г :- Т1, ..., Тn.
Застосунок системи доведення теорем обробляє такі твердження як процедури:
щоби показати/розв'язати Г, покажи/розв'яжи Т1 та ... та Тn.
Однак, чисту Пролог незабаром було розширено включенням заперечення як відмови, в якому заперечні умови форми not(Тi) показуються шляхом спроби і невдачі доведення відповідних позитивних умов Тi.
Подальші розширення Прологу оригінальною командою ввели до реалізацій можливості логічного програмування з обмеженнями[en].
Пролог використовувалася в комп'ютерній системі Watson. Watson використовує програмне забезпечення DeepQA компанії IBM та програмний каркас Apache UIMA[en] (англ. Unstructured Information Management Architecture, Архітектура Керування Неструктурованою Інформацією). Цю систему було написано багатьма мовами, включно з Java, C++ та Пролог, вона працює на операційній системі SUSE Linux Enterprise Server[en] 11 з використанням програмного каркаса Apache Hadoop для забезпечення розподілених обчислень. Пролог використовується для зіставлення зі зразками над синтаксичними деревами природної мови. Розробники цієї системи заявили:
![]() |
Ми потребували мови, якою ми могли би зручно виражати правила зіставлення зі зразками над синтаксичними деревами та іншими тлумаченнями (такими як результати розпізнавання іменованих сутностей), і технології, здатної виконувати ці правила дуже ефективно. Ми виявили, що Пролог була ідеальним вибором такої мови через свою простоту та виразність.[11]
Оригінальний текст (англ.) We required a language in which we could conveniently express pattern matching rules over the parse trees and other annotations (such as named entity recognition results), and a technology that could execute these rules very efficiently. We found that Prolog was the ideal choice for the language due to its simplicity and expressiveness. |
![]() |