|
НАЗАД
В языке Пролог при согласовании целей правила в процедуре выбираются в порядке их записи в программе. В рекурсивных программах порядок записи правил может оказаться весьма важным. Неудачное расположение правил может привести к бесконечным, рекурсивным вызовам, завершением которых является переполнение стека.
Чтобы обеспечить проверку условий завершения рекурсивных вызовов, рекомендуется нерекурсивное правило с условием выхода записывать перед рекурсивными правилами.
Вспомним программу «Родственные отношения».
родитель( пам, боб).
родитель( том, боб).
родитель( том, лиз).
родитель( боб, энн).
родитель( боб, пат).
родитель(пат; джим).
Давайте добавим к нашей программе о родственных связях еще одно отношение - предок. Определим его через отношение родитель. Все отношение можно выразить с помощью двух правил. Первое правило будет определять непосредственных (ближайших) предков, а второе - отдаленных. Будем говорить, что некоторый X является отдаленным предком некоторого Z, если между X и Z существует цепочка людей, связанных между собой отношением родитель-ребенок.
Первое правило простое и его можно сформулировать так:
Для всех X и Z,
X - предок Z, если
X - родитель Z.
Это непосредственно переводится на Пролог как
предок(X,Z):- родитель(X, Z).
Второе правило сложнее, поскольку построение цепочки отношений родитель может вызвать некоторые трудности. Один из способов определения отдаленных родственников мог бы быть таким, как показано в примере. В соответствии с ним отношение предок определялось бы следующим множеством предложений:
предок(X, Z):-родитель( X, Z).
предок(X, Z):-родитель( X, Y), родитель( Y, Z).
предок(X,Z):-родитель(X,Y1),родитель(Yl,Y2),родитель(Y2,Z).
предок(X,Z):-родитель(X,Y1),родитель(Yl,Y2),родитель(Y2,Y3),
родитель(Y3,Z).
Эта программа длинна и, что более важно, работает только в определенных пределах. Она будет обнаруживать предков лишь до определенной глубины фамильного дерева, поскольку длина цепочки людей между предком и потомком ограничена длиной наших предложений в определении отношения.
Существует, однако, корректная и элегантная формулировка отношения предок - корректная в том смысле, что будет работать для предков произвольной отдаленности. Ключевая идея здесь - определить отношение предок через него самого.
Для всех X и Z,
X - предок Z, если
существует Y, такой, что
(1) X - родитель Y и
|