Программирование на языке пролог
Шрифт:
Правило – это некоторое общее утверждение об объектах и об отношениях между ними.Например, мы можем сказать, что Фред является птицей, если Фред является живым существом и Фред имеет перья, мы можем также сказать, что Бертрам является птицей, если Бертрам является живым существом и Бертрам имеет перья. Таким образом, мы допускаем, что при каждом новом использованииправила переменная обозначает новый, отличный от прежнего объект. Конечно, в рамках конкретного использования правила переменные интерпретируются согласованно, как на это указывалось выше.
Рассмотрим несколько примеров, начав с правила, содержащего одну переменную и конъюнкцию:
Джону нравится любой, кому нравится
другими словами,
Джону нравится что-то, если чему-то нравится вино,
или, используя переменные,
Джону нравится X, если Xнравится вино.
В Прологе правило состоит из заголовкаи телаправила. Заголовок и тело соединяются с помощью символа :-, который состоит из двоеточия
Предыдущий пример записывается на Прологе следующим образом:
нравится(джон,X):- нравится(Х,вино).
Отметим, что правила также заканчиваются точкой. Заголовком этого правила является нравится(джон,Х). Заголовок правила описывает факт, для определения которого предназначено это правило. Тело правила, в данном случае нравится(Х,вино), описывает конъюнкцию целей, которые должны быть последовательно согласованы с базой данных, для того чтобы заголовок правила был истинным. Например, мы можем сделать Джона более разборчивым в выборе тех, кто ему нравится, просто добавив к телу правила еще несколько целевых утверждений, разделив их запятыми:
нравится(джон,X):- нравится(Х,вино), нравится(X,пища).
или, другими словами, Джону нравится любой, кому нравятся вино и пища.Или, предположим, что Джону нравится любая женщина, которой нравится вино:
нравится(джон,Х):- женщина(Х), нравится(Х,вино).
Всякий раз, когда мы имеем дело с правилом в Прологе, необходимо отмечать все вхождения переменных. В последнем примере переменная Xиспользована три раза. Всякий раз, как переменная X конкретизируется некоторым объектом (ей присваивается значение), все вхождения Xв пределах области действия этой переменнойстановятся конкретизированными. При каждом употреблении правила область действияпеременной X– это все правило, начиная с заголовка и до точки '.' в конце этого правила. Так, если в приведенном выше правиле переменная X оказалась конкретизированной, принимая значение мэри,то Пролог попытается согласовать с базой данных целевые утверждения женщина(мэри)и нравится(мэри,вино).
Теперь, чтобы продемонстрировать правило, использующее более одной переменной, рассмотрим базу данных, содержащую факты о семействе королевы Виктории. Мы будем использовать предикат родители,имеющий три аргумента. родители(Х, Y, Z)означает: Родителями X являются Y и Z. Переменная Yобозначает мать, а переменная Zобозначает отца. Кроме того, мы будем использовать предикаты женщинаи мужчинав их очевидном значении. Некоторая часть этой базы данных могла бы выглядеть следующим образом:
мужчина(альберт).
мужчина(эдуард).
женщина(алиса).
женщина(виктория).
родители(эдуард,виктория,альберт).
родители(алиса,виктория,альберт).
Здесь мы воспользуемся описанным ранее правилом является_сестрой.Правило определяет предикат является_сестрой, имеющий два аргумента, таким образом, что является_сестрой(X, Y)истинно, если Xявляется сестрой Y. Обратим внимание на использование в имени предиката символа подчеркивания '_'. Хотя до сих пор не было дано полных правил конструирования имен, отметим, что допускается использование подчеркивания в именах, а более подробно об этом будет сказано в следующей главе. Тогда Xявляется сестрой Y, если:
• Xявляется женщиной,
• Xимеет мать Ми отца Fи
• Yимеет тех же мать и отца, что и X.
Это можно записать в виде следующего правила Пролога:
является_сестрой(X,Y):- женщина(X), родители(X,M,P), родители(Y,M,P).
Мы используем переменные Mи Fдля обозначения материи отца,хотя при желании мы могли бы использовать имена Матьи Отец. Отметим, что мы употребляем переменные, которые не появляются в заголовке правила. Эти переменные, Mи F, обрабатываются таким же образом, как и любая другая переменная. Когда Пролог использует это правило, переменные Mи Fизначально будут неконкретизированными. Этим переменным будет присвоено некоторое значение в момент установления соответствия для предиката родители(X,M,F). Однако, как только они конкретизируются, становятся конкретизированными и всевхождения переменных Mи F, соответствующие текущему использованию правила. Следующий пример должен помочь объяснить, как используются эти переменные. Давайте зададим вопрос:
?- является_сестрой(алиса,эдуард).
Имея описанные выше базу данных и правила является_сестройи получив такой вопрос, Пролог выполняет следующие действия:
1. Сначала вопрос сопоставляется с единственным правилом для предиката является_сестрой, приведенным выше. При этом переменная Xконкретизируется, принимая значение алиса, и переменная Yконкретизируется значением эдуард. Правило, с которым произошло сопоставление, отмечается маркером. Теперь Пролог пытается последовательно согласовать с базой данных три предиката, входящие в тело правила.
2.Так как на предыдущем шаге переменной Xприсвоено значение алиса, то первой целью является женщина(алиса). Истинность этого предиката следует из списка фактов, так что цель достигнута. Поскольку данная цель согласована, то Пролог отмечает соответствующее ей место в базе данных (третье утверждение в базе данных).При этом не произошлоникаких присвоений значений переменным. Далее Пролог пытается согласовать следующую цель.
3. Теперь Пролог ищет соответствие для предиката родители(алиса,M,F), где переменные Mи Fсопоставимы с любыми аргументами, так как первоначально они неконкретизированы. Факт, с которым происходит сопоставление, есть родители(алиса, виктория,альберт), и тем самым вторая цель достигнута. Пролог отмечает маркером соответствующее место в базе данных (шестое утверждение сверху) и записывает, что Mприсвоено значение виктория, a F– значение альберт. (Если хотите, вы можете делать соответствующую запись над целевым утверждением в правиле.) Затем Пролог пытается найти соответствие для следующего предиката в правиле.