Смекни!
smekni.com

Язык логического программирования Visual Prolog (стр. 3 из 9)

Задание типов аргументов при декларации предикатов

Объявление доменов аргументов в разделе predicates называется заданием типов аргументов. Предположим, имеется следующая связь объектов:

Франк — мужчина, которому 45 лет.

Факт Пролога, соответствующий этому предложению естественного языка, может быть следующим:

person(frank, male, 45).

Для того чтобы объявить person (человек), как предикат с этими тремя аргументами, вы можете разместить в разделе predicates следующую строку:

person(symbol, symbol, unsigned).

Здесь для всех трех аргументов использованы стандартные домены. Отныне всякий раз при работе с предикатом person, вы должны передавать ему три аргумента, причем первые два должны быть типа symbol, а третий — типа integer.

Если в программе используются только стандартные домены, то нет необходимости использовать раздел domain; вы уже видели несколько программ такого типа.

Или, предположим, что вы хотите описать предикат, который сообщал бы позицию буквы в алфавите, т. е. цель

alphabet_position(Letter, Position)

должна вернуть вам Position = 1, если Letter = a, Position = 2, если Letter = Ь и т. д. Предложения этого предиката могут выглядеть следующим образом:

alphabet_position(A_character, N).

Если при объявлении предиката используются только стандартные домены, то программе не нужен раздел domains. Предположим, что вы хотите описать предикат так, что цель будет истинна, если A_character является N-м символом алфавита. Предложения этого предиката будут такими:

alphabet_position('а', 1). alphabet_position('b', 2).

alphabet_position('с', 3).

alphabet_position(' z1, 26).

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

predicates

alphabet_position(char, unsigned)

и тогда вам не будет нужен раздел domains. Если разместить все фрагменты программы вместе, получим:

predicates

alphabet_position(char, integer)

clauses

alphabet_position('a', 1).

alphabet_position('b', 2) .

alphabet_position('c', 3).

% здесь находятся остальные буквы

alphabet_position('z', 26).

Ниже представлено несколько простых целей, которые вы можете использовать:

alphabet_position ('а', 1).

alphabet_position(X, 3).

alphabet_position (' z', What).

Арность (размерность)

Арность предиката — это количество аргументов, которые он принимает. Вы можете иметь два предиката с одним и тем же именем, но отличающейся арностью. В разделах predicates и clauses версии предикатов с одним именем и разной арностью должны собираться вместе; за исключением этого ограничения, различная арность всегда понимается как полное различие предикатов. Проиллюстрируемэтопримером/

domains

person = symbol

predicates

father(person)% этот person — отец

father(person, person)% первый person является отцом другого

clauses

father (Man) :-father(Man, _) .

father(adam,seth).

father(abraham,isaac).

Синтаксис правил

Правила используются в Прологе в случае, когда какой-либо факт зависит от истинности другого факта или группы фактов. Как мы объясняли ранее в этой главе, в правиле Пролога есть две части: заголовок и тело. Ниже представлен обобщенный синтаксис правила в VisualProlog:

HEAD: - <Subgoal>, <Subgoal>, ..., <Subgoal>.

Заголовок: — <Подцель>, <Подцель>, ... , <Подцель>.

Тело правила состоит из одной или более подцелей. Подцели разделяются запятыми, определяя конъюнкцию, а за последней подцелью правила следует точка.

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

Для успешного разрешения правила Пролог должен разрешить все его подцели и создать последовательный список переменных, должным образом связав их. Если же одна из подцелей ложна, Пролог вернется назад для поиска альтернативы предыдущей подцели, а затем вновь двинется вперед, но уже с другими значениями переменных. Этот процесс называется поиск с возвратом.

Как упоминалось выше, в качестве разделителя заголовка и тела правила Пролог использует знак:-, который читается как "если" (if). Однако if Пролога отличается от if, написанного в других языках, например в Pascal, где условие, содержащееся в операторе if, должно быть указано перед телом оператора, который может быть выполнен. Другими словами:

если ЗАГОЛОВОК истинен, тогда ТЕЛО истинно (или: тогда выполнить ТЕЛО

Данный тип оператора известен как условный оператор если/тогда (if/then). Пролог же использует другую форму логики в таких правилах. Вывод об истинности заголовка правила Пролога делается, если (после того, как) тело этого правила истинно, например, так:

ЗАГОЛОВОК истинен, если ТЕЛО — истинно (или: если ТЕЛО может Сыть выполнено).

Учитывая вышесказанное, правило Пролога соответствует условной форме тогда/если (then/if).

Автоматическое преобразование типов

Совсем не обязательно, чтобы при сопоставлении двух VisualProlog-переменных они принадлежали одному и тому же домену. Переменные могут быть связаны с константами из различных доменов. Такое (избирательное) смешение допускается, т. к. VisualProlog автоматически выполняет преобразование типов (из одного домена в другой), но только в следующих случаях:

· между строками (string) и идентификаторами (symbol);

· между целыми, действительными и символами (char). При преобразовании символа в числовое значение этим значением является величина символа в коде ASCII.

Аргумент из домена my_dom, который объявлен следующим образом:

domains

my_dom = <base domain> % <base domain> — это стандартный домен

может свободно смешиваться с аргументами из этого основного домена и с аргументами всех совместимых с ним стандартных доменов. Если основной домен — string, то с ним совместимы аргументы из домена symbol; если же основной домен integer, то с ним совместимы домены real, char, word и др. Такое преобразование типов означает, например, что вы можете:

· вызвать предикат с аргументами типа string, задавая ему аргументы типа symbol, и наоборот;

· передавать предикату с аргументами типа real параметры типа integer;

· передавать предикату с аргументами типа char параметры типа integer;

· использовать в выражениях и сравнениях символы без необходимости получения их кодов в ASCII.

Существует набор правил, определяющих, к какому домену принадлежит результат смешивания разных доменов. Эти правила будут детально рассмотрены далее.

15. Другие разделы программ

Теперь, когда вы ознакомились с такими разделами программ VisualProlog, как clauses, predicates, domains и goal, поговорим о некоторых других, часто используемых разделах программ: facts, constants и различных глобальных (global) разделах.

Раздел фактов

Программа на VisualProlog представляет собой набор фактов и правил. Иногда в процессе работы программы бывает необходимо модифицировать (изменить, удалить или добавить) некоторые из фактов, с которыми она работает. В этом случае факты рассматриваются как динамическая или внутренняя база данных, которая при выполнении программы может изменяться. Для объявления фактов программы, рассматривающихся как части динамической (или изменяющейся) базы данных, VisualProlog включает специальный раздел — facts.

Ключевое слово facts объявляет раздел фактов. Именно в этой секции вы объявляете факты, включаемые в динамическую базу данных. Отметим, что в ранних версиях VisualProlog для объявления раздела фактов использовалось ключевое слово database, т. е. ключевое слово facts — синоним устаревшего ключевого слова database. В VisualProlog есть несколько встроенных предикатов, облегчающих использование динамических фактов.

Раздел констант

В своих программах на VisualProlog вы можете объявлять и использовать символические константы. Раздел для объявления констант обозначается ключевым словом constants, за которым следуют сами объявления, использующие следующий синтаксис:

<id> = <Макроопределение>

<id>— имя символической константы, а <макроопределение> — это то, что вы присваиваете этой константе. Каждое <макроопределение> завершается символом новой строки и, следовательно, на одной строке может быть только одно описание константы. Объявленные таким образом константы могут позже использоваться в программах.