Чтение онлайн

на главную - закладки

Жанры

Программирование на языке пролог
Шрифт:
atomic(X)

Целевое утверждение atomic(X)согласуется с базой данных, если на текущий момент Xобозначает либо целое число, либо атом. Предикат atomicможет быть определен через предикаты atomи integerследующим образом:

atomic(X):- atom(X).

atomic(X):- integer(X)

6.4. Работа с утверждениями как с термами

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

предикаты, позволяющие программисту следующее:

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

• Добавлять к базе данных утверждение, представленное заданной структурой.

• Удалять из базы данных утверждение, представленное заданной структурой.

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

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

нравится(джон,Х)

может рассматриваться как обычная структура с функтором нравится(имеющим два аргумента) и аргументами джони X.С другой стороны, правило можно рассматривать как структуру с главным функтором ':-'(с двумя аргументами). Этот функтор объявлен как инфиксный оператор. Первым аргументом является заголовок утверждения, а вторым – его тело. Так что

нравится(джон, X):- нравится(Х,вино)

есть не что иное, как

':-' (нравится(джон,Х), нравится(Х,вино))

– совершенно обычная структура. Далее, если правило содержит более одного целевого утверждения, то они считаются объединенными в структуры с функтором ',' (с двумя аргументами). Этот предикат также объявлен как инфиксный оператор. Так что

прародитель(Х, Z):- родитель(Х, Y), родитель(Y,Z)

есть в действительности просто

':-'(прародитель(Х,Z),Y(родитель(Х,Y),родитель(Y, Z))

Далее приведены предикаты, позволяющие программисту анализировать и изменять его утверждения.

listing (A)

Выполнение целевого утверждения listing(A),когда значением Аявляется атом, приводит к тому, что все утверждения, предикат которых совпадает с этим атомом, будут записаны в виде термов Пролога в текущий файл вывода. Таким способом вы можете проверить, какие утверждения для некоторого предиката имеются в базе данных на текущий момент. Конкретный формат представления выводимых утверждений зависит от используемой вами реализации Пролог-системы. Заметим, что будут представлены все утверждения, предикат которых совпадает с атомом независимо от того, сколько аргументов они имеют. Использование предиката listingможет помочь вам обнаружить ошибки в программе. Так, в приведенном далее примере сеанса работы с системой программист обнаруживает, что он неправильно определил предикат обр.

?- [test].

test consulted

да

?- обр([a,b,c,d],X).

нет

?- listing(обр).

обр([],[]).

обр ([_44|_45],_38):-обр(_45,_47),присоединить(_47,[_44],_38).

да

Печать утверждений предиката обрпоказывает, что атом присоединитьнаписан в программе с ошибкой.

clause(X, Y)

Выполнение целевого утверждения вида clause(X, Y)приводит к тому, что Xи Yсопоставляются с заголовком и телом некоторого имеющегося в базе данных утверждения. При попытке выполнить указанное целевое утверждение переменная Xдолжна быть до такой степени конкретизирована, чтобы был известен главный предикат утверждения. Если для данного предиката нет утверждений, то доказательство

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

Заметим, что в то время как предикат clauseвсегда имеет аргумент, соответствующий телу утверждения, далеко не каждое утверждение действительно имеет тело. Если утверждение не имеет тела, то считается, что оно имеет фиктивное тело true.Мы называли такие утверждения «фактами». В той или иной степени конкретизируя Xи Y, можно искать либо все утверждения, соответствующие данному предикату с вполне определенным числом аргументов, либо все утверждения, соответствующие некоторому образцу. Так, например:

присоединить([], X, X).

присоединить([А|В]),С,[А|D]:- присоединить(В,С,D).

?- clause(присоединить(А,В,С),Y).

А=[], В =_23, С=_23, Y = true;

А = [_23|_24], В =_25, С = [_23|_26], Y = присоединить(_24,_25,_26);

нет

Предикат clauseочень полезен в том случае, если нам надо создать программы, анализирующие или исполняющие другие программы (см. разд. 7.13).

asserta(X), assertz(X)

Два встроенных предиката assertaи assertzпозволяют добавлять новые утверждения в базу данных. Оба предиката действуют в точности одинаковым образом, за тем исключением, что assertaдобавляет утверждение в началобазы данных, в то время как assertzдобавляет утверждение в ее конец.Это отличие можно легко запомнить, учитывая, что « а» является первой буквой английского алфавита, a « z» его последняя буква. При выполнении целевого утверждения asserta(X), Xдолжно иметь значением нечто, что можно представлять как утверждение; действительно, как и в случае clause, Xдолжно быть достаточно конкретизировано, чтобы можно было установить главный предикат. Необходимо подчеркнуть, что результат добавления в базу данных утверждения не устраняется при выполнении возврата. Следовательно, если мы использовали предикат assertaили assertzдля того, чтобы добавить новое утверждение, то это утверждение может быть удалено только в случае, если мы явно укажем это (используя предикат retract).

retract(X)

Встроенный предикат retractпозволяет удалять утверждения из базы данных. Этот предикат имеет один аргумент, представляющий терм, с которым должно быть сопоставлено удаляемое утверждение. Указанный терм должен быть достаточно конкретизирован, чтобы можно было определить предикат утверждения (аналогично предикатам asserta, clauseи т. д.). При попытке выполнить целевое утверждение retract(X)находится первое утверждение в базе данных, с которым может быть сопоставлен X, и это утверждение удаляется. При попытке вновь выполнить это целевое утверждение Пролог просматривает базу данных, начиная с места удаленного утверждения, в попытке найти другое сопоставимое утверждение. Если такое утверждение находится, то выполняются действия, рассмотренные выше. Если делается новая попытка согласовать целевое утверждение, то продолжается поиск следующего подходящего утверждения. И так далее. Заметим, что если утверждение было удалено, то оно ни при каких условиях не будет восстановлено вновь, даже при попытке вновь выполнить предикат retractпри возврате. Если в некоторый момент поиск не дает новых сопоставлений утверждений, то согласование целевого утверждения заканчивается неудачей.

Так как аргумент Xсопоставляется с удаляемым утверждением, то имеется возможность получить точное представление об удаляемом утверждении, даже если Xисходно означал некоторую структуру, содержащую множество неконкретизированных переменных. Это позволяет использовать предикат retractвместо предиката clause, в ситуации когда найденное утверждение сразу же удаляется. Такая ситуация как раз имеет место в определении предиката генатом (разд. 7.8).

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец