Теория языков программирования

Логическое программирование

Что если бы вместо написания алгоритма поиска можно было просто описать, что нужно найти, и компьютер сам разобрался как? Именно это делает логическое программирование. Sudoku на Prolog - 10 строк. SEND+MORE=MONEY - 15 строк. Timetabling для университета - 50 строк.

  • **Erlang**: синтаксис pattern matching и унификации прямо из Prolog - Ericsson сделал из Prolog-идей производительный concurrent язык для телекоммуникаций
  • **TypeScript type inference**: алгоритм вывода типов использует унификацию - когда TS выводит тип generic функции, это тот же алгоритм Робинсона что и в Prolog
  • **Google Optimization Tools (OR-Tools)**: constraint programming внутри решает задачи fleet routing для Google Maps, vehicle scheduling для логистики Amazon

Prolog и Resolution

В Prolog программа - это набор фактов и правил (Horn clauses). Запрос - цель, которую система пытается доказать. Вместо написания алгоритма программист описывает отношения между объектами, а Prolog сам ищет решение через SLD-resolution.

Prolog используется в: IBM Watson (частично), Erlang (синтаксис заимствован), GNU Prolog для constraint solving. Amazon Alexa использует Prolog-подобный движок для NLP.

Что является программой в Prolog?

Унификация

Унификация - алгоритм нахождения подстановки переменных, при которой два терма становятся идентичными. Это ключевая операция в Prolog, а также в системах типов (Hindley-Milner type inference) и pattern matching.

Алгоритм Робинсона (1965) для унификации: O(n) с union-find. Hindley-Milner type inference в Haskell/OCaml использует ту же унификацию для вывода типов. Когда GHC говорит 'Cannot match Int with Bool' - это провал унификации.

Чем унификация отличается от присваивания переменных?

Бэктрекинг

Когда Prolog не может доказать цель с текущими привязками, он откатывается (backtrack) к последней точке выбора и пробует следующую альтернативу. Это автоматический поиск в пространстве решений через depth-first search.

Prolog бэктрекинг - DFS по дереву доказательств. Для задачи N Queens с N=8 Prolog решает за миллисекунды. Для N=20 - может потребоваться секунды без оптимизаций. Constraint Logic Programming резко сокращает пространство поиска.

Что происходит при бэктрекинге в Prolog?

Constraint Logic Programming

CLP расширяет Prolog ограничениями (constraints) вместо чистой унификации. Вместо перебора всех значений система распространяет ограничения и сразу отсекает невозможные области. CLP(FD) для целых чисел, CLP(R) для вещественных.

Современные применения: Minizinc (constraint modeling language) для scheduling, timetabling, resource allocation. Google OR-Tools (C++/Python) использует CLP внутри. Clojure.core.logic - миниатюрный Prolog в Clojure.

Prolog - медленный учебный язык, не используется в продакшене

SWI-Prolog используется в продакшене: IBM Watson, StackOverflow's answer ranking, Erlang заимствовал синтаксис

Медленность Prolog - миф при правильном использовании. CLP(FD) для combinatorial problems быстрее наивного Python. Проблема не в скорости, а в крутой кривой обучения

Почему CLP(FD) решает задачу SEND+MORE=MONEY значительно быстрее чистого перебора?

Ключевые идеи

  • **Prolog** - декларативная парадигма: описываем что верно (факты + правила), система сама доказывает через SLD-resolution
  • **Унификация** - алгоритм нахождения подстановки переменных. Та же основа у Hindley-Milner type inference в Haskell/OCaml
  • **Бэктрекинг** - автоматический DFS по дереву доказательств. cut (!) прекращает бэктрекинг
  • **CLP** - ограничения вместо перебора. SEND+MORE=MONEY: 10^8 -> ~1000 проверок благодаря propagation

Связанные темы

Логическое программирование влияет на типы и языки:

  • Системы типов — Hindley-Milner type inference - это унификация, заимствованная из логического программирования
  • Верификация программ — Model checking и theorem provers используют те же формальные методы

Вопросы для размышления

  • Унификация в Prolog и type inference в Haskell используют один алгоритм. Что это говорит о глубинной связи между логикой и системами типов?
  • Бэктрекинг - сложный инструмент, но может быть экспоненциально медленным. Когда стоит использовать CLP вместо чистого Prolog?
  • Clojure.core.logic позволяет вставлять логическое программирование в обычный Clojure код. Как бы вы использовали это для задачи поиска конфигурации в системе с зависимостями?

Связанные уроки

  • logic-29-predicates-intro
Логическое программирование

0

1

Войти