Які основні технічні відмінності між Prolog та miniKanren щодо логічного програмування? [зачинено]


124

Коли я хочу прочитати логічне програмування, я завжди натрапляю на два "основні" способи зробити це сьогодні:

  • miniKanren , міні-мова, представлена ​​в The Reasoned Schemer і популярна на даний момент завдяки core.logic .
  • Prolog , перша "велика" логічна мова програмування.

Що мене зараз цікавить: Які основні технічні відмінності між ними? Чи дуже вони схожі за підходом та реалізацією, чи приймають зовсім інші підходи до логічного програмування? З яких галузей математики вони походять і які теоретичні основи?


3
Сумно бачити це питання закритим. Як свідчить дуже зухвала відповідь та велика кількість відгуків, це цілком корисне питання. Я проголосував за повторне відкриття ....
nealmcb

@nealmcb запитань, які колись були на тему з багатьма оновленнями, більше не може бути, кількість оновлень не те, що визначає її чи ні.
Tiago Martins Peres 李大仁

Відповіді:


281

По-перше, дозвольте мені похвалити вас за ваш прекрасний значок pw0n1e.

На це складний питання, на який слід відповісти, багато в чому тому, що існує так багато варіантів як miniKanren, так і Prolog. miniKanren і Prolog - це справді сімейства мов, що ускладнює порівняння їх особливостей або навіть того, як вони використовуються на практиці. Зважаючи на це, будь ласка, прийміть все, про що я говорю, з обережністю: якщо я скажу, що Prolog використовує пошук в глибині перших, майте на увазі, що багато реалізацій Prolog підтримують інші стратегії пошуку, і що альтернативні стратегії пошуку також можуть бути закодовані в мета -інтерпретаційний рівень. Тим не менш, miniKanren і Prolog мають різні філософії дизайну і роблять різні компроміси.

Prolog - одна з двох класичних мов для символічного програмування штучного інтелекту (інша класична мова - Lisp). Prolog досконалий у застосуванні символічних систем, заснованих на правилах, де декларативні знання кодуються логікою першого порядку. Мова оптимізована для виразності та ефективності для таких типів додатків, іноді за рахунок логічної чистоти. Наприклад, Prolog за замовчуванням не використовує "перевірку виникнення" в уніфікації. З точки зору математики / логіки, ця версія об'єднання є неправильною. Однак перевірка виникнення є дорогою, і в більшості випадків відсутність перевірки на виникнення не є проблемою. Це дуже прагматичне дизайнерське рішення, як і використання програми Prolog для пошуку в глибині перших і використання вирізання (!) для управління зворотним трекінгу. Я впевнений, що ці рішення були абсолютно необхідні при роботі з обладнанням 1970-х років, і сьогодні вони дуже корисні при роботі над великими проблемами та при роботі з величезними (часто нескінченними!) Пошуковими просторами.

Prolog підтримує безліч "екстралогічних" або "нелогічних" функцій, включаючи вирізання assertта retractпроекцію змінних для арифметики з використаннямis, і так далі. Багато з цих функцій полегшують вираження складного потоку управління та маніпулювання глобальною базою фактів Prolog. Однією з дуже цікавих особливостей Prolog є те, що сам код Prolog зберігається у глобальній базі даних фактів, і його можна попросити під час виконання. Це змушує тривіально писати метаінтерпретатори, які змінюють поведінку коду Prolog під інтерпретацією. Наприклад, можна кодувати перший широту пошуку в Prolog за допомогою метаінтерпретатора, який змінює порядок пошуку. Це надзвичайно потужна техніка, яка недостатньо відома за межами світу Пролога. "Мистецтво Пролога" докладно описує цю техніку.

Величезні зусилля були спрямовані на вдосконалення впроваджень Prolog, більшість з яких базується на абстрактній машині Warren (WAM). WAM використовує побічну модель, в якій значення деструктивно присвоюються логічним змінним, при цьому ці побічні ефекти скасовуються під час зворотного відстеження. Багато функцій можна додати до Prolog, розширивши інструкції WAM. Одним із недоліків такого підходу є те, що документи про впровадження Prolog можуть бути важкими для читання без чіткого розуміння WAM. З іншого боку, у впровадника Prolog є спільна модель для обговорення проблем із впровадженням. Паралельно з Прологом було проведено велику кількість досліджень, кульмінацією якої стала Андора Пролог у 90-х роках. Принаймні, деякі з цих ідей живуть у провінції Ciao Prolog. (Ciao Prolog сповнений цікавих ідей, багато з яких виходять далеко за рамки стандарту Prolog.)

Prolog має прекрасний синтаксис "узгодження" шаблону на основі уніфікації, що призводить до дуже лаконічних програм. Прологери люблять свій синтаксис так само, як і Лісперс люблять свої s-вирази. У Prolog також є велика бібліотека стандартних предикатів. Завдяки всій техніці, яка переросла в WAM швидко, є дуже здібні та зрілі реалізації Prolog. Як результат, багато великих систем, заснованих на знаннях, були повністю написані в Prolog.

miniKanren був розроблений як мінімальна логічна мова програмування, з невеликою, легко зрозумілою і легко руйнується реалізацією. miniKanren спочатку був вбудований у схему та був перенесений на десятки інших мов хосту протягом останнього десятиліття. Найпопулярніша реалізація miniKanren - це 'core.logic' у Clojure, який тепер має багато розширень, подібних до Prolog, та низку оптимізацій. Останнім часом ядро ​​реалізації miniKanren ще більше спростилося, в результаті чого крихітне "мікроядро" називається "microKanren". miniKanren може бути реалізований поверх цього ядра microKanren. Перенесення microKanren або miniKanren на нову мову хоста стало стандартною вправою для програмістів, які навчаються miniKanren. Як результат,

Стандартні реалізації miniKanren та microKanren не містять мутацій та інших побічних ефектів, за єдиним винятком: деякі версії miniKanren використовують рівність покажчика для порівняння логічних змінних. Я вважаю це "доброякісним ефектом", хоча багато реалізацій уникають навіть цього ефекту, передаючи лічильник через реалізацію. Також немає глобальної бази даних фактів. Філософія впровадження miniKanren натхненна функціональним програмуванням: мутації та ефектів слід уникати, а всі мовні конструкції повинні дотримуватися лексичної сфери. Якщо ви уважно подивитесь на реалізацію, ви можете навіть помітити пару монад. Реалізація пошуку заснована на поєднанні та маніпулюванні ледачими потоками, знову ж таки без використання мутації. Такі варіанти впровадження призводять до зовсім інших компромісів, ніж у Prolog. У Prolog змінний пошук - це постійний час, але зворотне відстеження вимагає скасування побічних ефектів. У miniKanren змінний пошук дорожчий, але зворотній трек "безкоштовний". Насправді, у miniKanren немає зворотнього огляду, завдяки тому, як обробляються потоки.

Одним із цікавих аспектів реалізації miniKanren є те, що код за своєю суттю є безпечним для потоків та --- принаймні теоретично, - тривіально паралелізованим. Звичайно, паралелізація коду, не роблячи його повільніше , не є тривіальною, враховуючи, що кожному потоку чи процесу потрібно надати достатньо роботи, щоб компенсувати накладні витрати на паралелізацію. І все-таки це сфера впровадження miniKanren, яка, сподіваюся, отримає більше уваги та експериментів.

miniKanren використовує перевірку виникнення для об'єднання і використовує повний переплетений пошук замість першого глибинного пошуку. Пошук з перемежуванням використовує більше пам’яті, ніж перший на глибині пошуку, але може знайти відповіді в деяких випадках, коли пошук на глибині першого буде назавжди розходитися / циклічно. miniKanren робить підтримку кілька екстра-логічні оператори --- conda, conduі project, наприклад. condaі conduможе бути використаний для імітації розрізу Prolog і projectможе бути використаний для отримання значення, пов'язаного з логічною змінною.

Наявність conda, conduіproject--- і можливість легко змінювати стратегію пошуку --- дозволяє програмістам використовувати miniKanren як вбудовану мову, що нагадує пролог. Особливо це стосується користувачів 'core.logic' Clojure, що включає безліч розширень, подібних до Prolog. Це "прагматичне" використання miniKanren, здається, пояснює більшість використання miniKanren у промисловості. Програмісти, які хочуть додати систему міркувань на основі знань до існуючої програми, написаної на Clojure або Python або JavaScript, як правило, не зацікавлені переписувати всю свою програму в Prolog. Вставлення невеликої мови логічного програмування в Clojure або Python набагато привабливіше. Вбудована реалізація Prolog працювала б так само добре для цієї мети, імовірно.

Окрім використання miniKanren як прагматичної вбудованої логічної мови програмування, подібної за духом до Prolog, miniKanren використовується для досліджень у "реляційному" програмуванні. Тобто при написанні програм, які ведуть себе як математичні відносини, а не математичні функції. Наприклад, у схемі appendфункція може додавати два списки, повертаючи новий список: виклик функції (append '(a b c) '(d e))повертає список (a b c d e). Однак ми можемо також трактувати appendяк відношення у трьох місцях, а не як функції двох аргументів. Потім виклик (appendo '(a b c) '(d e) Z)асоціює змінну логіки Zзі списком (a b c d e). Звичайно, речі стають цікавішими, коли ми розміщуємо логічні змінні в інших позиціях. Виклик (appendo X '(d e) '(a b c d e))пов'язується Xз (a b c), під час дзвінка(appendo X Y '(a b c d e))асоційовані Xі Yз парами списків, які при додаванні дорівнюють (a b c d e). Наприклад X= (a b)і Y= (c d e)є одна така пара значень. Ми також можемо написати (appendo X Y Z), що буде виробляти нескінченно багато трійок списків X, Yі Zтаким чином, що додавання Xдо Yвиробляють Z.

Ця реляційна версія appendможе бути легко виражена в Prolog, і вона дійсно показана у багатьох навчальних посібниках. На практиці більш складні програми Prolog, як правило, використовують принаймні декілька поза логічних можливостей, таких як вирізання, які гальмують можливість трактувати отриману програму як відношення. Навпаки, miniKanren явно призначений для підтримки цього стилю реляційного програмування. Пізніші версії miniKanren має підтримку рішення символічного обмежень ( symbolo, numbero,absento, обмеження нерівності, номінальне логічне програмування) для полегшення запису нетривіальних програм як відносин. На практиці я ніколи не використовую жодної екстралогічної функції miniKanren, і всі свої програми miniKanren я пишу як відносини. Найцікавіші реляційні програми - це реляційні перекладачі для підмножини Схеми. Ці інтерпретатори мають багато цікавих здібностей, наприклад, генеруючи мільйон (I love you)схемних програм, які оцінюються до списку , або тривіально генерують лайки (програми, які оцінюють самі).

miniKanren робить ряд компромісів, щоб дозволити цей стиль реляції програмування, який сильно відрізняється від компромісів, які робить Prolog. З часом miniKanren додав більше символічних обмежень, ставши справді символічно орієнтованою логікою програмування обмежень. У багатьох випадках ці символічні обмеження дозволяють уникнути використання поза логічних операторів, таких як conduі project. В інших випадках цих символічних обмежень недостатньо. Краща підтримка символічних обмежень є одним із активних напрямків дослідження miniKanren разом із більш широким питанням про те, як писати більші та складніші програми як відносини.

Коротше кажучи, і miniKanren, і Prolog мають цікаві функції, реалізацію та використання, і я думаю, що варто вивчити ідеї з обох мов. Є й інші дуже цікаві мови логічного програмування, такі як Меркурій, Керрі та Гьодель, кожна з яких має власне прийняття логічного програмування.

Я закінчу кількома ресурсами miniKanren:

Основний веб-сайт miniKanren: http://minikanren.org/

Інтерв'ю, яке я дав про реляційне програмування та miniKanren, включаючи порівняння з Prolog: http://www.infoq.com/interviews/byrd-relational-programming-minikanren

Ура,

- Буде


9
Вибачте, якщо мене зараз підірве. Я щойно розпочав перші мислячі експерименти з логіки та обмеження на програмуванні, і це я отримав відповідь. :) Насправді, як ви вже згадували у своїй відповіді, у мене була сильна підозра на логіку, що обчислення було ідеальним кандидатом для реалізації як Монада; виявляється, це більше MonadPlus, і дійсно є робота з документами та довідками від вашого колеги Фрідмана! Тож я читаю це і зараз граю з ним, якісь думки з цього приводу?
Profpatsch

4
Я підозрюю, що ви також знайдете папір та код microKanren цікавими: webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdf та github.com/jasonhemann/microKanren
William E. Byrd

5
Також я організовую щотижневий міні-курс "Канкрен" по Google Hangouts, неділі о 15:00 за східним часом (GMT -5: 00). Я завжди твітую посилання зі свого облікового запису @webyrd Twitter, якщо ви хочете приєднатися до нас. Попередні записані відеокімнати за адресою: youtube.com/playlist?list=PLO4TbomOdn2cks2n5PvifialL8kQwt0aW
William E. Byrd

2
Я думаю, що це в основному та сама пошукова монада, що і в документі '05. Також дивіться "Вставлення прологу в Haskell" від Seres and Spivey: spivey.oriel.ox.ac.uk/~mike/silvija/seres_haskell99.pdf
William E. Byrd

1
@ WilliamE.Byrd - Чудова відповідь! Якщо припустити, що таке найкраща реалізація miniKanren, яку можна вбудувати в програму C / C ++? Також, чи має miniKanren генеративний характер Prolog? Тобто, можливість залишити змінну в виразі неземною, а основний двигун генерує всі можливі значення для незмінної змінної з урахуванням поточних співвідношень, оголошених програмою?
Роберт Ошлер

4

Орієнтовна відповідь:

AFAIK, "The Reasoned Schemer" представив базове логічне програмування в синтаксисі Scheme-y та функціональному стилі програмування, додавши, зокрема, постійні цілі "#u" (невдача) та "#s" (запускається) до булевих значень "#t "і" #f ". Він застосував такий самий підхід до логічного програмування, як і Prolog: Уніфікація та зворотний пошук. Я побачу, чи маю якийсь час, щоб витягнути цю книгу зі своєї полиці протягом вихідних. Галузь математики - це логіка першого порядку з обмеженою формою, в даному випадку пункти Хорна та Розв'язання. Дивіться: Обчислювальна логіка: Спогади про минуле та виклики майбутнього Джона Алана Робінсона та перші роки логічного програмування Роберта Ковальського для холодного початку.


3
Які ці цитати мають відношення до Kanren чи MiniKanren?
фальшивий

2
Дивіться останнє запитання: "З яких галузей математики вони походять, і які теоретичні основи?"
Френк Ширар
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.