Опубликован: 06.11.2008 | Уровень: специалист | Доступ: платный | ВУЗ: Ярославский Государственный Университет им. П.Г. Демидова
Лекция 8:

Язык Пролог: вычисления и процедурная семантика Пролога

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Аннотация: Алгоритм вычислений программы на Прологе: порядок рассмотрения атомов в запросе; вызов процедуры для атома; интерпретация переменных и замена атома запроса; ветвление при невозможности интерпретации; правило остановки вычислений; примеры вычислений запросов для программы родства и программы соединения списков; сходство Пролога с языками нормальных алгоритмов Маркова и Рефалом.

Вычисления и процедурная семантика Пролога

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

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

Мы будем описывать алгоритм вычислений, одновременно рассматривая и поясняя его на примере.

Пример 1. Рассмотрим запрос

<- предок (X, петр)

для программы предыдущего раздела.

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

2. При вызове процедуры мы по очереди рассматриваем формулы (правила или факты) этой процедуры.

Шаг 1. В данном примере для процедуры предок мы берем сначала первое правило для этой процедуры, но делаем регулярную замену переменных:

предок (X1, Y1) <- мать (X1, Y1).

Вызов процедуры предок ( X, петр ) совпадает с заголовком этого правила при интерпретации: X=X1, Y1= петр.

3. Производим интерпретацию переменных заголовка (правила или левой части факта) и заменяем прежний атомарный запрос на запрос тела процедуры, в котором произведена полученная интерпретация переменных.

4. Если интерпретация невозможна, то необходимо перейти к предыдущей точке выбора формулы процедуры. Если при этом нет предыдущей точки выбора, то вычисления закончились неуспешно.

В примере получаем запрос

<- мать (X1, петр).

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

мать(X2, Y2) <-,

которые допускают интерпретацию Y2 = петр. Так как таких нет, то вычисление закончилось неудачно и нужно вернуться к предыдущей точке алгоритма, где мы можем сделать следующий выбор. Такой точкой является шаг 1, где мы выбирали правило процедуры предок.

Шаг 3. Выбираем следующее правило процедуры \unde предок с заменой переменных:

предок (X1, Y1) <- отец (X1, Y1).

Вызов процедуры предок ( X, петр ) совпадает с заголовком этого правила при интерпретации: X1=X, Y1 = петр. Заменяем исходный запрос на тело процедуры с полученной интерпретацией переменных и получаем новый запрос:

<- отец (X1, петр).

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

отец (X2, Y2)<-,

которые допускают интерпретацию X2 = X1, Y2 = петр. Есть 1 такой факт

отец (иван, петр) <-,

который дает интерпретацию X2=иван.

5. Как только замена заголовка процедуры на тело дает пустой запрос, который является истинным, вычисления исходного запроса (атома) заканчиваются успешно.

Делая обратные подстановки иван = X2 = X1 = X, получаем первый ответ X=иван.

Теперь необходимо вернуться к предыдущей точке выбора формулы.

Шаг 5. В процедуре предок выбираем следующее правило с заменой переменных:

предок (X1, Y1) <- предок (Z1, Y1), мать (X1, Z1).

Вызов процедуры предок (X, петр) совпадает с заголовком этого правила при интерпретации: X1=X, Y1= петр. Заменяем исходный запрос на тело процедуры с полученной интерпретацией переменных и получаем новый запрос:

<- предок (Z1,петр), мать (X1, Z1).

Мы получили запрос с 2 атомами и должны рассматривать их по очереди.

Шаг 6. Рассматриваем запрос с первым атомом

<- предок (Z1,петр) В процедуре предок выбираем первое правило (первое, потому что это новый запрос в нашем вычислении) с заменой переменных:

предок (X1, Y1) <- мать (X1, Y1).

Вызов процедуры предок (X, петр) совпадает с заголовком этого правила при интерпретации: Z1=X1,Y1=петр. Делая замену на тело этой процедуры (с интерпретацией переменных), получаем запрос:

<- мать (X1, петр)

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

предок (X1, Y1) <- отец (X1, Y1).

Вызов процедуры предок (X, петр) совпадает с заголовком этого правила при интерпретации: X1=Z1,Y1=петр. Заменяем исходный запрос на тело процедуры с полученной интерпретацией переменных и получаем новый запрос:

<- отец (X1, петр).

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

отец (X2, Y2) <-,

которые допускают интерпретацию X2=X1, Y2=петр. Есть 1 такой факт

отец (иван, петр) <-,

который дает интерпретацию X2 = иван. Вычисления запроса для первого атома шага 5 закончились успешно, и мы получаем интерпретацию Z1 = иван, которую используем во втором атоме запроса, рассматриваемом на следующем шаге.

Шаг 8. Рассматриваем второй атом запроса с интерпретацией переменной Z1:

<- мать (X1, иван).

Так как процедура мать представляет собой множество фактов, то рассматриваем лишь такие факты

мать(X2, Y2) <-,

которые допускают интерпретацию X2 = X1, Y2 = иван. Есть 1 такой факт

мать (елена, иван) <-,

который дает интерпретацию X2 = елена. Так как это факт, то вычисления второго атома запроса также закончились успешно. В результате получаем елена = X2=X1=X, и, следовательно, второй ответ X = елена.

Теперь для завершения вычислений нужно вернуться к предыдущей точке выбора и рассмотреть последнее правило процедуры предок:

предок (X1, Y1) <- предок (Z1, Y1), отец (X1, Z1).

Мы опять получили запрос с 2 атомами и должны рассматривать их по очереди.

< Лекция 7 || Лекция 8: 12 || Лекция 9 >
Игорь Суркин
Игорь Суркин
Россия, г. Магнитогорск
Акбар Ахвердов
Акбар Ахвердов
Россия, г. Москва