11
1.4. Факты и правила в Прологе
Описанный выше запрос, устанавливающий отношение типа
"прародитель-внук" может потребоваться в дальнейшем неоднократно. В этой
связи его целесообразно запомнить для дальнейшего использования в других
запросах. В базе знаний Пролога можно хранить не только факты, но и правила,
т.е. условные отношения. Отношение типа "прародитель-внук
" может быть
записано следующим образом:
grandparent(X,Y) if parent(X,Z), parent(Z,Y).
Читать это нужно следующим образом: X является прародителем Y, если X
является родителем Z и Z является родителем Y. Предикат grandparent(X,Y)
называется заголовком правила, а выражение справа от if – телом правила.
Примечание: Синонимом связки "if" в правиле являются символы ":-".
Таким образом, как и в базах
данных, в базе знаний Пролога в виде фактов
мы храним первичные знания, а производные от них записываем в виде правил,
к которым обращаемся так же, как и к фактам.
Факт – это то, что известно.
Правило – это способ порождения новых фактов на основе имеющихся.
Для родственных отношений мы можем установить множество правил
,
избавляясь от необходимости вводить дополнительные факты, например, кто
кому приходится братом, племянником и т.д. Правило, определяющее
отношение брат (сестра):
sibling(X,Y) :- parent(Z,X), parent(Z,Y), X<>Y.
Предикат сравнения X<>Y нужен для разрешения коллизии типа "сын
моего отца, но мне не брат". Правило, определяющее отношение типа дядя,
выглядит следующим образом:
uncle(X,Y) :- parent(Z,Y), sibling(X,Z).
Когда в ходе резолюции цели
Пролог встречает не факт, а правило, то
вначале унифицирует заголовок правила, т.е. сравнивает связанные переменные
и присваивает значения свободным переменным. В случае успешной
унификации аргументов Пролог подставляет значения аргументов из заголовка
в первый предикат в теле правила и ставит этот предикат себе в качестве
подцели, которую начинает унифицировать с
базой знаний. В случае успешной
резолюции данной подцели Пролог переходит к следующему условию правила.
Если унификация этого предиката условия приводит к неудаче, то Пролог
выполняет откат к предыдущему условию правила. Этот откат происходит
только в том случае, если этот предыдущий предикат является неоднозначным.
Поясним это на примере. Зададимся целью найти, кто
является прародителем
Кристины:
grandparent(Who, kristina).
Получив такую цель, Пролог начинает унифицировать ее с правилом:
grandparent(X,Y) :- parent(X, Z), parent(Z,Y). Переменная Who в предикате цели
является свободной переменной и ее унификация с переменной X в заголовке
правила будет успешной всегда. Следует заметить, что в Прологе все