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

А.А.Морозов

Институт радиотехники и электроники РАН

1. О том, почему мы стали работать в этой области, и что именно нас не устраивает в современном состоянии логического программирования

В настоящее время в логическом программировании можно выделить две тенденции, два подхода, которых часто придерживаются исследователи.

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

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

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

Пример негативных последствий второго подхода - история развития объектно-ориентированного логического программирования. Сейчас в области процедурного программирования "на уровне идей" существуют понятия "объект", "класс", "наследование". Программисты привыкли без глубокого анализа воспринимать их как нечто цельное, и переносят эти понятия в логические языки, моделируя их при помощи различных средств, не имеющих четкой логической семантики (таких как базы данных, not, отсечение, метасредства и т.п.). В результате было создано большое количество языков (например, Prolog++, LogTalk и др.), которые логическими уже не являются (так как их идеология, парадигма программирования существенным образом опираются на нелогические средства), но при этом "настоящими" объектно-ориентированными языками так и не стали.

2. Чем отличается наш подход?

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

3. Что удалось сделать?

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

Действительно, для любого предиката p(A,B,C,...) существует множество подстановок, которые делают его истинным или ложным. А вот если мы возьмем "псевдопредикат" read(X) в Прологе, то, поскольку человек один раз вводит одно значение, другой раз - другое, никакой логической семантики как бы вообще нет. На самом деле, понятно, почему так получилось. Логические языки "пришли" из области автоматического доказательства теорем. А там ввод-вывод не нужен - надо задать условия задачи, а потом машина ее решает, и никаких операций ввода-вывода не нужно. Но Пролог это, все-таки, не prover, это язык программирования, и поэтому мы обязаны ввести в идеологию языка ввод-вывод.

Надо сразу сказать, что в той модели взаимодействия человека и машины, в рамках которой мы решали названную проблему, мы не используем операторы ввода-вывода read и write. Вместо того чтобы пытаться построить "навороченную" семантику для этих операторов, мы разработали некоторую новую парадигму человеко-машинного интерфейса, которая, как будет показано ниже, оказалась даже ближе к современным представлениям о том, что такое интерактивный режим, и принципам, которые применяются в современных графических интерфейсах в OS/2, Windows и т.п.

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

  • Отдельные подцели независимы друг от друга. То есть они связаны общими переменными, но при этом могут доказываться независимо друг от друга, в произвольном порядке.
  • Далее, когда все эти подцели доказаны, это значит, что доказана вся теорема.
  • И самое главное: мы имеем возможность произвольным образом, в произвольный момент времени отменить результаты доказательства любой такой подцели и доказать ее повторно.

Что это дает?

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

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

Здесь можно сразу сделать два замечания:

  • Во-первых, предложенная модель очень напоминает те, что используются в современных интерактивных системах. Это то, что называется реактивными системами или системами, управляемыми событиями. Та же самая идея: предоставить пользователю среду, на которую он может воздействовать.
  • И, во-вторых, здесь мы видим пример того, как наложение строгих логических ограничений на реальную действительность привело к появлению нового принципа обработки информации.

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

4. Что такое акторы и Акторный Пролог?

Повторно доказываемые подцели, о которых рассказывалось выше, мы назвали "акторами", по аналогии с акторной моделью вычислений Хьюитта. Термин актор (английский actor) по смыслу можно перевести как "действующее лицо", "объект, взаимодействующий с другими объектами".

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

Первая публикация об Акторном Прологе была в журнале "Программирование" в 1994 г. (номер 5), в ней описаны основные идеи и средства языка. С тех пор мы продолжали работу над языком. В частности, мы разработали полное определение Акторного Пролога и издали его в виде препринта ИРЭ РАН. Это делалось не для того, чтобы создать еще один язык программирования, а для того чтобы "пощупать руками", какие проблемы возникают при реализации и практической работе с языком, основанном на предложенных идеях.

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

http://www.cplire.ru/Lab144/index.html

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

5. Как это применяется на практике?

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

Вывод

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


Back to Research Divisions
IRE RAS Homepage