Ярославский Государственный Университет им. П.Г. Демидова
Опубликован: 06.11.2008 | Доступ: свободный | Студентов: 988 / 62 | Оценка: 4.50 / 4.00 | Длительность: 10:47:00
Лекция 8:

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

< Лекция 7 || Лекция 8: 12 || Лекция 9 >

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

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

Он аналогичен запросу, рассмотренному на шаге 6, и потому его вычисление приводит к правилу

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

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

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

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

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

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

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

<- отец (X1, иван).

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

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

которые допускают интерпретацию Y2=иван. Таких фактов нет, эти вычисления закончились неудачно. Поскольку мы перебрали все формулы процедуры предок, то вычисления закончены. Окончательно получаем множество ответов:

X={иван, елена}.

В рассмотренном примере аргументами предикатных термов запросов являлись константные объекты и переменные. Однако если аргументы имеют более сложную природу, например являются списками или составными термами, то при сравнении запроса и заголовка процедуры необходимо идентифицировать все части запроса с учетом их структуры. Для этого обычно рассматривают дерево атома запроса и дерево заголовка процедуры для этого атома, и, для того чтобы их отождествить, необходимо получить одинаковую структуру обоих деревьев. Рассмотрим следующий пример со списками.

Пример 2. Рассмотрим правило App склеивания списков (от append - присоединение к списку). Оно выражается следующими фактом и правилом:

App(nil; X; X) <-
App(U:X; Y; U:Z) <- App(X; Y; Z),

которые означают, что

  1. результатом склеивания списка X с пустым списком является список X ;
  2. 2) если результат склеивания списков X и Y есть список Z, то результат склеивания списков u.X и Y есть список U.Z.

Рассмотрим выполнение запроса

<- App (a:b:nil; b:nil; X),

при котором мы ожидаем получить X=a.b.b.nil.

Шаг 1. Пытаемся применить первое правило (факт)

App (nil, X1, X1) <-.

При отождествлении деревьев факта и запроса (см. рис. 8.1) получается недопустимая подстановка nil=a.b.nil. Поэтому отождествление невозможно, и этот шаг закончился неудачно.


Рис. 8.1.

Шаг 2. Пытаемся применить второе правило

App (U1.X1, Y1, U1.Z1) <- App (X1, Y1, Z1).

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

App (b.nil, b.nil, Z1) <-.


Рис. 8.2.

Шаг 3. Структура запроса определена деревом на рис. 8.3. Попытка применить правило 1 не дает результата, так как nil \ne  b.nil.


Рис. 8.3.

Шаг 4. Пытаемся применить правило 2:

App (U2.X2, Y1, U2.Z2) <- App (X2, Y2, Z2).

Отождествление запроса и левой части правила возможны только при интерпретации, показанной на рис. 8.3. Делая подстановку в запрос и заменяя на правую часть правила, получаем запрос:

<- App (nil, b.nil, Z2).

Структура его дерева показана на рис. 8.4.


Рис. 8.4.

Шаг 5. Пытаемся применить правило 1:

App (nil, X3, X3)<-.

Отождествление этого запроса и левой части правила возможны только при интерпретации, показанной на рис. 8.4. Делая подстановку и заменяя на тело правила, получаем пустой запрос, что свидетельствует о благополучном завершении интерпретаций. Подставляя значение Z2 в выражение для Z1, а затем значение Z1 - в выражение для X, получим X = a.Z1 = a.b.Z2 = a.b.b.nil, что и требовалось.

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

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

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

Упражнения

  1. Проведите для упражнения 3.6.1 пошаговые вычисления.
  2. Проведите для упражнения 3.6.2 пошаговые вычисления.
  3. Проведите для упражнения 3.6.3 пошаговые вычисления.
  4. Проведите для упражнения 3.6.4 пошаговые вычисления.
  5. Измените правила базы знаний из упражнения 3.6.1 так, чтобы можно было выполнить запрос, строящий цепочки включающих друг друга кодов, начиная от заданного программного кода.
< Лекция 7 || Лекция 8: 12 || Лекция 9 >