Структура программы и основная терминология

В учебных пособиях по языкам программирования обычно используют один из двух подходов к представлению материала. При одном подходе изложение начинается с описания структур данных языка, его синтаксиса и т. д., при другом — сначала приводится пример программы, который дает обучаемому возможность составить начальное представление о языке, ознакомиться с некоторыми его особенностями, а затем изложение строится так же, как и в первом случае. Второй способ кажется более предпочтительным, так как сразу вводит читателя в мир нового языка, делает его чуть более знакомым, понятным, улучшает дальнейшее восприятие. Следуя второму подходу, рассмотрим структуру программы на языке Пролог и связанные с ней основные понятия на основе простых примеров.

Пример. Требуется описать группу людей и их пристрастия к различным видам спорта: domains

person, active = symbol predicates

like (person, activ) clauses

like (ellen, tennis) .

like (bob, football).

like (jon, tennis) .

like (mark, basketball).

like (bill, X) if like (jon, X).

Раздел clauses содержит множество фактов и правил. Факты like (ellen, tennis) и like (bob, football) соответствуют следующим утверждениям: «Элен любит теннис» и «Боб любит футбол», остальные организованы аналогично. Для формирования утверждения о Билле использвуется правило like (bill, X) if like (jon, X), которое на естественном языке это звучит так: «Билл любит X, если Джон любит X».

Как уже говорилось ранее, программа на языке Пролог определяет базу знаний, в которой хранятся соответствующие объекты и отношения, заданные на них, т. е. сама по себе такая программа неприменима. Конкретному применению программы соответствует введение цели, для задания которой существует раздел goal. Ввод цели можно рассматривать как формулирование запроса к базе знаний, ответ на который строится самой Пролог-программой. Таким образом, если определять в одной и той же программе разные цели, то можно получить различные варианты ответов. По умолчанию считается, что Пролог ищет все возможные решения для заданной цели.

Например, сформируем запрос like (ellen, tennis), его цель — определить, соответствует ли истине тот факт, что «Элен любит теннис». Пролог выдаст true, так как у него есть факт, подтверждающий это утверждение. Аналогичный ответ будет и в случае запроса like (bill, tennis), но его истинность будет подтверждена не фактом, а правилом, которое истинно, так как имеет место факт like (jon, tennis), выполнение которого является условием выполнения правила.

Если ввести like (bill, football), то будет выдано no solution, так как нет правила, подтверждающего этот запрос на основе имеющихся фактов, и нет факта, подтверждающего этот запрос.

В правиле like (bill, X) if like (jon, X) буква«X» использовалась как переменная, обозначающая неизвестный вид деятельности.

Имена переменных должны начинаться с заглавной (прописной) буквы, вслед за которой могут идти в любом количестве строчные или заглавные буквы, цифры или знаки подчеркивания («_»). Поэтому имена First_Name, True25m3 допустимы, namel, second-name, 25zrt — не допустимы. Осмысленный выбор имен переменных, как и в других языках программирования, делает программу на Прологе более наглядной. Максимальная длина имени — 250 знаков.

В Прологе различают свободные и связанные переменные. Переменная считается свободной, если ей не присвоено никакого значения; как только ей присваивается некоторое значение, переменная становится связанной. Статус переменой существенно влияет на действия, которые можно с ней выполнить. Например, обычная операция «=» работает по- разному в зависимости от того, свободная переменная или связанная.

Рассмотрим выражение ы=м. Если N — свободная переменная, а м — связанная, то произойдет обычное присваивание. Если обе переменные связанные, то будет выполнена операция сравнения, которая выдаст значение true или false. Если обе переменные свободные или м — свободная, а N — связанная, то будет выдано сообщение об ошибке, так как Пролог будет считать такую операцию некорректной. Свободные переменные не могут участвовать в арифметических операциях в качестве аргументов. В Прологе невозможно выполнить операцию инкремента х = х+1, так как в этом случае необходимо либо переназначить значение связанной переменной, либо выполнить операцию сложения со свободной переменной, что недопустимо.

Переменные можно использовать не только в правилах, но и в запросах. С учетом этого на основе имеющейся программы можно получить не только подтверждение запроса, но и другие варианты ответа. Если ввести запрос like (Ind, tennis), то для его удовлетворения требуется найти всех, кто любит теннис. Будет найдено три варианта ответа:

Ind = ellen Ind = jon Ind = bill

Домены и предикаты. Факты и правила, входящие в раздел clauses, представляют собой отношения (предикаты), которые связывают один или несколько объектов. Все отношения, используемые в программе, должны быть описаны в разделе predicates. Для объектов необходимо специфицировать домены (типы данных), которым принадлежат объекты, участвующие в отношениях. Для этого в Прологе, как и в других языках, зарезервирован набор стандартных типов данных. Описание объектов происходит в разделе domains. Например, раздел описаний приведенной выше программы показывает, что в отношении like участвуют два объекта, принадлежащие символьному (symbol) домену. Очевидно, что несоответствие между объявленными в описании типами доменов и реально указанными в разделе clauses фактическими параметрами приведет к ошибке.

Например, like (12, X) — неверно, так как 12 не принадлежит символьному домену; like (ellen, jon, tennis) приведет к ошибке, так как отношение like имеет не три, а два аргумента.

Для описания отношений и объектов можно выбирать любые имена, удовлетворяющие следующим требованиям:

  • имена объектов должны начинаться со строчной буквы, за которой может следовать произвольное число символов (букв, цифр, знаков подчеркивания);
  • имена отношений — произвольные комбинации букв, цифр, знаков подчеркивания, начинающихся со строчных букв.

Например, допустимые отношения:

car (model, color, age), nolike (dog, cat) .

В одном отношении могут участвовать объекты, принадлежащие различным доменам. Например, описание автомобиля, для которого указана марка, цвет, год выпуска и стоимость может выглядеть так: domains

model, color = symbol age = integer price = real predicates

car (model, color, age, price)

Составные цели. Часто требуется вводить запросы, удовлетворяющие нескольким условиям. Такая цель называется составной целью. Например, для предыдущего описания требуется получить информацию об автомобиле, цена которого меньше 10 000:

car (Model, Colort, Age, Price) and Price < 10000. Решая эту задачу, Пролог должен будет удовлетворять двум подцелям, указанным в предикате саг и отношении «<» (меньше), которое является стандартным (встроенным).

Анонимные переменные. Бывают ситуации, когда для некоторых переменных не требуется конкретного значения, т. е. они могут принимать любые значения и на результат не влияют. Тогда в запросе можно вместо этой переменной указать знак подчеркивания «_», который обозначает анонимную переменную и говорит о том, что значение этого параметра будет игнорироваться. Так, если необходимо узнать только марку автомобиля, можно записать:

car (Model, _, _, _, Price) and Price < 10000 и получить в ответ информацию о марках всех машин с ценой меньше 10 000.

Анонимную переменную можно использовать везде, где допустимо использование любой другой переменной, она никогда не получает конкретного значения, т. е. знак подчеркивания обозначает переменную, которая не представляет интереса. Анонимные переменные можно использовать в фактах. Например, факт «все читают книги» можно представить так: read (_, book).

Решение составных целей и возврат. Как уже говорилось, в Прологе реализован механизм поиска всех возможных решений для заданной цели, поэтому в тех случаях, когда в обычных языках требовалось бы использовать несколько вложенных циклов, в Прологе достаточно правильно определить составную цель.

Пример. Рассмотрим следующую программу, которая содержит данные об учениках класса, для каждого из которых указывается имя и возраст: domains

child = symbol age = integer predicates

pupl (child, age) clauses

pupl (bob, 9) .

pupl (tom, 10). pupl (cris, 9). pupl (mark, 9).

Требуется составить таблицу турнира для игры в пинг-понг (по две игры на каждую пару) при условии, что возраст участников — девять лет. Воспользуемся составной целью:

pupl (Persl, 9) and pupl (Pers2, 9) and Persl <> Pers2. В качестве результата Пролог выдаст группу ответов, по которым легко оценить ход поиска решения:

Persl = bob Pers2 = cris

Persl = bob Pers2 = mark

Persl = cris Pers2 = bob

Persl = cris Pers2 = mark

Persl = mark Pers2 = bob

Persl = mark Pers2 = cris

В заключение этого пункта рассмотрим еще один пример — «Пролог в роли свахи».

Пример. Требуется написать программу, которая по заданному набору параметров подобрала бы достойную кандидатуру для свидания. Определим два варианта реализации такой системы. Будем считать, что в обоих случаях подбирается кандидат-мужчина. В качестве параметров для оценки определим следующие: спортсмен, вегетарианец, курильщик.

Для описания каждого кандидата, информация о котором хранится в базе данных, будем использовать предикат person с четырьмя параметрами.

domains

sports, vegit, smok = symbol name = symbol predicates

person (name, sports, vegit, smok) ok_person (sports, vegit, smok) clauses

person (rob, yes, no, no). person (bob, no, no, yes). person (pit, yes, yes, no). person (smit, yes, no, yes). person (bill, yes, no, no).

ok_person (S, V, Sm) if not (person (_, S, V, Sm) ), write ("Подходящей кандидатуры нет"), nl, exit.

ok_person (S, V, Sm) if person (X, S, V, Sm) , write ("Скорее всего это-", X), fail, nl.

goal

ok_person (yes, no, yes).

Следует еще обратить внимание на то, что Пролог проверяет факты и правила всегда сверху вниз, т. е. по порядку их расположения в тексте программы, поэтому, изменяя порядок следования предикатов, можно изменить и получаемый результат.

Примечание. В программе были использованы предикаты write, exit, not, nl, fail, которые не описаны в разделе predicates. Эти предикаты входят в состав системы и называются стандартными. Они обычно используются для реализации типовых действий, таких как ввод-вывод, обработка строк и др., и их описывать не нужно. Особое внимание следует обратить на предикат fail, который заставляет Пролог искать все возможные решения для поставленной цели.

 
Посмотреть оригинал
< Пред   СОДЕРЖАНИЕ   ОРИГИНАЛ   След >