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

ЖАНРЫ

Программирование на языке Пролог для искусственного интеллекта

Братко Иван

Шрифт:

no

7.3. Различные виды равенства

В каких случаях мы считаем, что два терма равны? До сих пор мы рассматривали три вида равенства в Прологе. Первый был связан с сопоставлением и записывался так:

X = Y

Это равенство верно, если X и Y сопоставимы. Следующий вид равенства записывался в виде

X is E

Такое равенство выполняется, если X сопоставим со значением арифметического выражения E. Мы также рассматривали равенства вида

Е1 =:= Е2

которые верны, если равны значения арифметических выражений Е1 и Е2. Наоборот, если значения двух

арифметических выражений не равны, мы пишем

Е1 =/= Е2

Иногда нам может понадобиться более строгий вид равенства - буквальное равенство двух термов. Этот вид реализован еще одним встроенным предикатом, записываемым как инфиксный оператор '

==
':

Т1 == Т2

Это равенство выполняется, если термы Т1 и Т2 идентичны, т.е. имеют в точности одинаковую структуру, причем все соответствующие компоненты совпадают. В частности, должны совпадать и имена переменных. Отношение "не идентичны", дополнительное к данному, записывается так:

T1 \== T2

Приведем несколько примеров:

?- f( a, b) == f( а, b).

yes

?- f( a, b) == f( a, X).

?- f( a, X) == f( a, Y).

no

?- X \== Y.

yes

?- t( X, f( a, Y) ) == t( X, f( a, Y) ).

yes

Давайте в качестве примера переопределим отношение

счетчик( Терм, Список, N)

из разд. 7.1. Пусть на этот раз N будет числом буквальных вхождений

Терм
'а в
Список
:

счетчик( _, [], 0).

счетчик( Терм, [Голова | L], N) :-

 Терм == Голова, !,

 счетчик( Терм, L, N1),

 N is N1 + 1;

счетчик( Терм, L, N).
 

7.4. Работа с базой данных

Реляционная модель предполагает, что база данных — это описание некоторого множества отношений. Пролог-программу можно рассматривать как именно такую базу данных: описание отношений частично присутствует в ней в явном виде (факты), а частично — в неявном (правила). Более того, встроенные предикаты дают возможность корректировать эту базу данных в процессе выполнения программ. Это делается добавлением к программе (в процессе вычисления) новых предложений или же вычеркиванием из нее уже существующих. Предикаты, используемые для этой цели, таковы:

assert
(добавить),
asserta
,
assertz
 и
retract
(удалить).

Цель

assert( С)

всегда успешна, а в качестве своего побочного эффекта вызывает "констатацию" предложения С, т.е. добавление его к базе данных.

Цель

retract( С)

приводит к противоположному эффекту: удаляет предложение, сопоставимое с С. Следующий диалог иллюстрирует их работу:

?- кризис.

no

?- assert( кризис).

yes

?- кризис.

yes

?- retract(
кризис).

yes

?- кризис.

no

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

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

хорошая :-

 солнечно, not дождь.

необычная :-

 солнечно, дождь.

отвратительная :-

 дождь, туман.

дождь.

туман.

Ниже приводится пример диалога с этой программой, во время которого база данных постепенно изменяется:

?- хорошая.

no

?- отвратительная.

yes

?- retract( туман).

yes

?- отвратительная.

no

?- assert( солнечно).

yes

?- необычная.

yes

?- retract( дождь).

yes

?- хорошая.

yes

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

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

быстр( энн).

медл( том).

медл( пат).

К этой программе можно добавить правило:

?- assert(

 ( быстрее( X, Y) :-

быстр( X), медл( Y) ) ).

yes

?- быстрее( А, В).

А = энн

В = том

?- retract( медл( X) ).

X = том;

X = пат;

?- быстрее( энн, _ ).

Заметьте, что при добавлении нового правила синтаксис требует, чтобы оно (как аргумент

assert
) было заключено в скобки.

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

asserta
 и
assertz
. Цель

asserta( С)

помещает С в начале базы данных. Цель

Поделиться с друзьями: