В retract/1
есть что-то, что для меня не имеет смысла.
Согласно ISO / IEC 13211-1: 1995:
8.9.3 retract / 1
8.9.3.1 Описание
retract(Clause)
верно, если база данных содержит хотя бы одну динамическую c процедуру с пунктом Clause
который объединяется с Head :- Body
.
Процедурно retract(Clause)
выполняется следующим образом:
a) Если Clause
объединяется с ':-'(Head, Body)
, то переходит к 8,9. 3.1 c,
b) Остальное объединяет Head
с Clause
и true
с Body
,
c) Последовательный поиск каждая динамическая c пользовательская процедура в базе данных и создает список L всех терминов clause(H, B)
, так что 1) база данных содержит предложение, заголовок которого можно преобразовать в термин H
(7.6.3), и тело которого можно преобразовать в член B
(7.6.4), и 2) H
объединяется с Head
, а 3) B
объединяется с Body
.
d) Если непустой список найден, затем переходит к 8.9.3.1 f,
e) В противном случае цель терпит неудачу.
f) Выбирает первый элемент списка L , удаляет соответствующее ему предложение из базы данных, и цель достигает цели.
g) Если были выбраны все элементы списка L , то цель не выполняется.
h) В противном случае выбирает первый элемент списка L , который еще не был выбран, удаляет предложение , если оно существует , соответствующее ему из базы данных, и цель успешна.
retract(Clause)
повторно исполняемый. На обратном пути продолжайте на 8.9.3.1 г. [...]
" Если существует"? Как могло случиться, что не больше не существует после повторного выполнения?
Семантика обновления базы данных предполагает, что "it" всегда существует:
7.5.4 Логическое обновление базы данных
Любое изменение в базе данных, возникающее в результате выполнения цели (например, когда активатором подцели является вызов assertz/1
или retract/1
) влияет только на активацию, выполнение которой начинается впоследствии. Это изменение не должно влиять на любую активацию, которая выполняется в данный момент.
ПРИМЕЧАНИЕ. - Таким образом, база данных замораживается во время выполнения цели, и список пунктов, определяющих предикацию, фиксируется в момент ее выполнения ( см. 7.7.7 e).
Ниже я попытался использовать retract(f(3))
для создания предложения f(3)
vani sh до повторного выполнения предыдущего retract(f(X))
:
?- abolish(f/1), maplist(assertz,[f(1),f(2),f(3)]).
true. % setup complete
?- retract(f(X)), ( X = 2 -> retract(f(3)) ; true ).
X = 1
; X = 2
<b>; X = 3</b>. % <----------------^^^^^^^^^^^^^
... но, увы, я потерпел неудачу: SICStus Prolog, GNU Prolog и SWI-Prolog дали одинаковые (выше) ответы.
Так зачем использовать фразу «если она существует» в этом контекст? Для меня это избыточно. И озадачивает ... помогите пожалуйста!