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