Мы можем остановить поток решений, набрав, например, точку вместо точки с запятой (выбор конкретного символа зависит от реализации).
Пролог-системе можно задавать и еще более сложные вопросы, скажем, кто является родителем родителя Иакова? Поскольку в нашей программе прямо не сказано, что представляет собой отношение родительродителя, такой вопрос следует задавать в два этапа.
Кто родитель Иакова?
Предположим, что это некоторый Y.
Кто родитель Y?
Предположим, что это некоторый X.
Такой составной вопрос на Прологе записывается в виде последовательности двух простых вопросов:
?- родитель( Y, иаков), родитель( X, Y).
Ответ будет:
X = авраам
Y = исаак
Наш составной вопрос можно интерпретировать и так: «Найти X и Y, удовлетворяющие следующим двум требованиям»:
родитель( Y, иаков) и родитель( X, Y)
Если мы поменяем порядок этих двух требований, то логический смысл останется прежним:
родитель( X, Y) и родитель( Y, иаков)
Этот вопрос можно задать нашей пролог-системе и в такой форме:
?- родитель( X, Y), родитель( Y, иаков).
При этом результат будет тем же. Таким же образом можно спросить: «Кто внуки Авраама?»
?- родитель(авраам, X), родитель( Х, Y).
Система ответит так:
X = авраам
Y = иаков
Следующим вопросом мог бы быть такой: «Есть ли у Фареса и Зары общий родитель?» Его тоже можно выразить в два этапа:
(1) Какой X является родителем Фареса?
(2) Является ли (тот же) X родителем Зары?
Соответствующий запрос к пролог-системе будет тогда выглядеть так:
?- родитель( X, фарес), родитель( X, зара).
Ответ:
X = иуда;
Х = фамарь
Теперь добавим к нашей программе о родственных связях еще одно отношение - предок. Определим его через отношение родитель. Ключевая идея здесь - определить отношение предок через него самого.
Для всех X и Z,
X - предок Z, если
существует Y, такой, что
(1) X - родитель Y и
(2) Y - предок Z.
Предложение Пролога, имеющее тот же смысл, записывается так:
предок( X, Z) :-
родитель( X, Y),
предок( Y, Z).
Теперь мы построили полную программу для отношения предок, содержащую два правила: одно для ближайших предков и другое для отдаленных предков. Здесь приводятся они оба вместе:
предок( X, Z) :-
родитель( X, Z).
предок( X, Z) :-
родитель( X, Y),
предок( Y, Z).
Ключевым моментом в данной формулировке было использование самого отношения предок в его определении. Такое определение может озадачить - допустимо ли при определении какого-либо понятия использовать его же, ведь оно определено еще не полностью. Такие определения называются рекурсивными. Логически они совершенно корректны и понятны. Но будет ли в состоянии пролог-система использовать рекурсивные правила? Оказывается, что пролог-система довольно легко может обрабатывать рекурсивные определения. На самом деле, рекурсия - один из фундаментальных приемов программирования на Прологе. Без рекурсии с его помощью невозможно решать задачи сколько-нибудь ощутимой сложности.
Возвращаясь к нашей программе, можно задать системе такой вопрос: «Кто потомки Авраама?» То есть: «Кто тот человек, чьим предком является Авраам?»
?- предок( авраам, X).
X = исаак;
X = иаков;
X = иуда;
X = фарес
…
Наша программа-пример помогла проиллюстрировать некоторые важные моменты, а именно:
На Прологе легко определить отношение, подобное отношению родитель, указав объекты, для которых это отношение выполняется.
Пользователь может легко задавать пролог-системе вопросы, касающиеся отношений, определенных в программе.
Пролог-программа состоит из предложений. Каждое предложение заканчивается точкой.
Аргументы отношения могут быть (среди прочего): конкретными объектами, или константами (такими, как авраам и иаков), или абстрактными объектами, такими, как X и Y. Объекты первого типа называются атомами. Объекты второго типа - переменными.
Вопросы к системе состоят из одного или более целевых утверждений (или кратко – целей). Последовательность целей, такая как
родитель( X, фарес), родитель( X, зара)
означает конъюнкцию этих целевых утверждений:
X - родитель Фареса и
X - родитель Зары.
Пролог-система рассматривает вопросы как цели, к достижению которых нужно стремиться.
Ответ на вопрос может оказаться или положительным или отрицательным в зависимости от того, может ли быть соответствующая цель достигнута или нет. В случае положительного ответа мы говорим, что соответствующая цель достижима и успешна. В противном случае цель недостижима, имеет неуспех или терпит неудачу.
Если на вопрос существует несколько ответов, пролог-система найдет столько из них, сколько пожелает пользователь.
Предложения могут быть заданы рекурсивно. |