В зависимости от вида вопросы языка Пролог делятся на несколько типов. Тип вопроса влияет как на его обработку алгоритмом логического вывода, так и на вид ответа.
Различные варианты вопросов удобно рассмотреть на примере предметной области, представляющей родственные отношения (для удобства будем нумеровать предложения, описывающие предметную область).
1) мать ( «Вера», «Юлия»);
2) мать («Вера», «Павел»);
3) мать («Мария», «Петр»);
4) мать («Анна», «Вера»);
5) отец («Петр», «Юлия»);
6) отец («Петр», «Павел»);
7) отец («Иван», «Петр»);
8) отец («Андрей», «Вера»);
9) дед (X,Y) : – отец(X,Z), мать (Z,Y);
10) дед (X,Y) : – отец(X,Z), отец (Z,Y) ;
11) бабка (X,Y) : – мать(X,Z), мать (Z,Y);
12) бабка (X,Y) : – мать(X,Z), отец (Z,Y);
Граф родственных отношений, представленный этой таблицей, выглядит следующим образом (верхние вершины дуг – родители, нижние – дети):
Рассмотрим типы вопросов.
1) Вопросы, в целях которых отсутствуют переменные.
С помощью таких вопросов пользователь может спросить, верно или нет некоторое предположение (свойство, отношение). Например:
«Верно ли, что отцом Юлии является Петр?» На Прологе:
? – отец(«Петр», «Юлия»)
Или: «Верно ли, что Павел является дедушкой Марии?» На Прологе:
? – дед(«Павел», «Мария»)
На первый вопрос должен быть дан положительный ответ, который система выдаст в виде: Yes. Ответ на второй вопрос отрицательный:No.
Вопросы этого типа могут быть и составными, например:
«Верно ли, что Анна является бабушкой, а Андрей дедушкой Юлии?»
? – бабка(«Анна», «Юлия»), дед(«Андрей», «Юлия»).
Ответ: Yes.
Или: «Верно ли, что отцом и матерью Петра являются Иван и Мария?»
? – отец(«Иван», «Петр»), мать(«Мария», «Петр»).
Ответ: No.
Заметим, что во втором вопросе первая цель представлена правильным предположением, а вторая – неправильным. Так как для положительного ответа требуется, чтобы все предположения были правильными, в данном случае дается отрицательный ответ.
2) Вопросы с использованием переменных (не анонимных).
Семантика этих вопросов совсем другая. С их помощью пользователь может узнать, для каких объектов предметной области выполнены свойства или отношения, указанные в вопросе. Например:
«Кто является отцом Юлии?». На Прологе:
? – отец (Х, «Юлия»).
Или: «Укажите дедушек и бабушек Павла». На Прологе:
? – дед(Х, «Павел»), бабка(Y, «Павел»).
В ответах на вопросы этого типа перечисляются значения переменных, при которых предикаты вопросов являются истинными. На первый вопрос будет дан ответ:
Х = «Петр».
1 Solution.
На второй вопрос будет получен ответ:
Х = «Андрей», Y = «Анна»
Х = «Иван», Y = «Мария».
2 Solutions.
Вопрос может быть таким, что вариантов ответов на него нет, например: «Кто является дедушкой Петра?»
? – дед(Х, «Петр»).
Тогда ответ системы будет выглядеть так:
No Solution.
3) Вопросы, в которых используется анонимная переменная.
Анонимная переменная играет в Прологе особую роль. С ее помощью пользователь может узнать, существуют ли в предметной области такие объекты, для которых его предположение оказывается истинным. При этом его интересует лишь существование таких объектов, но не они сами. Например: «Известен ли хоть один дедушка Юлии?» Или: «Указаны ли в предметной области внуки Петра?» На Прологе:
? – дед(_, «Юлия»).
? – дед(«Петр», _).
Ответы на подобные вопросы представляются в такой же форме, как в случае вопросов первого типа: YesиNoсоответственно.
Как видно из приведенных типов вопросов, при отсутствии анонимных переменных их обработка предполагает полный перебор выводов (так как необходимо найти все варианты ответов). Если в вопросе используется анонимная переменная, перебор может быть сокращен. Так, обрабатывая вопрос ? – дед(_, «Юлия»),системе достаточно обнаружить одного деда, хотя как видно из схемы родственных отношений примера, в БЗ их двое.
Приведем пример работы алгоритма логического вывода, представив ее в виде таблицы со следующими полями:
1) №№ варианта и шага вывода. Так как потребуется перебор, будет осуществляться возврат на уже выполненные шаги с целью поиска других вариантов их выполнения. Возврат будет осуществляться с помощью процедуры бэктрекинга.
2) Список целей.
3) № предложения (факта или правила), выбранного для резолюции.
4) Унификатор
5) Стек возвратов, используемый процедурой бэктрекинга. Задается в виде: пар: № шага, на который нужно вернуться, и № первого предложения, с которого нужно продолжить просмотр.
6) Примечания.
Пусть пользователь ввел вопрос: ? – дед(«Иван»,Х).Работа алгоритма логического вывода может быть представлена следующей таблицей:
№№ шаг. и вар.
список целей
№ предл.
унификатор
Стек возвратов
примеч.
1.1
дед(«Иван», Х)
{(Х, «Иван»), (Y, Х)}
(1,10)
2.1
отец(«Иван» ,Z), мать(Z, Х)
{(Z, «Петр»)}
(1,10), (2,8)
3.1
мать(«Петр», Х)
–
–
(1,10), (2,8)
Тупик
2.2
отец(«Иван» ,Z), мать(Z, Х)
–
–
(1,10)
Тупик
1.3
дед(«Иван», Х)
{(Х, «Иван»), (Y, Х)}
(1,11)
2.3
отец(«Иван» ,Z), отец(Z, Х)
{(Z, «Петр»)}
(1,11), (2,8)
3.3
отец(«Петр», Х)
{(Х, «Юлия»)}
(1,11), (2,8), (3,6)
4.3
L
–
–
(1,11), (2,8), (3,6)
Получен 1-ый вывод
3.4
отец(«Петр», Х)
{(Х, «Павел»)}
(1,11), (2,8), (3,7)
4.4
L
–
–
(1,11), (2,8), (3,7)
Получен 2-ый вывод
3.5
отец(«Петр», Х)
–
–
(1,11), (2,8), (3,8)
Тупик
2.6
отец(«Иван» ,Z), мать(Z, Х)
–
–
(1,11)
Тупик
1.7
дед(«Иван», Х)
–
–
–
Тупик.
Так как после шага 1.7 стек возвратов оказался пустым, полный перебор осуществлен и алгоритм логического вывода заканчивает работу. В результате будет сформирован ответ: