Previous Up Next

8.7  Dynamic clause management

8.7.1  Introduction

Static and dynamic procedures: a procedure is either dynamic or static. All built-in predicates are static. A user-defined procedure is static by default unless a dynamic/1 directive precedes its definition (section 7.1.2). Adding a clause to a non-existent procedure creates a dynamic procedure. The clauses of a dynamic procedure can be altered (e.g. using asserta/1), the clauses of a static procedure cannot be altered.

Private and public procedures: each procedure is either public or private. A dynamic procedure is always public. Each built-in predicate is private, and a static user-defined procedure is private by default unless a public/1 directive precedes its definition (section 7.1.3). If a dynamic declaration exists it is unnecessary to add a public declaration since a dynamic procedure is also public. A clause of a public procedure can be inspected (e.g. using clause/2), a clause of a private procedure cannot be inspected.

A logical database update view: any change in the database that occurs as the result of executing a goal (e.g. when a sub-goal is a call of assertz/1 or retract/1) only affects subsequent activations. The change does not affect any activation that is currently being executed. Thus the database is frozen during the execution of a goal, and the list of clauses defining a predication is fixed at the moment of its execution.

8.7.2  asserta/1, assertz/1

Templates

asserta(+clause)
assertz(+clause)

Description

asserta(Clause) first converts the term Clause to a clause and then adds it to the current internal database. The predicate concerned must be dynamic (section 8.7.1) or undefined and the clause is inserted before the first clause of the predicate. If the predicated is undefined it is created as a dynamic procedure.

assertz(Clause) acts like asserta/1 except that the clause is added at the end of all existing clauses of the concerned predicate.

Converting a term Clause to a clause Clause1:

Converting a term T to a goal:

Errors

Head is a variable  instantiation_error
Head is neither a variable nor a callable term  type_error(callable, Head)
Body cannot be converted to a goal  type_error(callable, Body)
The predicate indicator Pred of Head is that of a static procedure  permission_error(modify, static_procedure, Pred)

Portability

ISO predicates.

8.7.3  retract/1

Templates

retract(+clause)

Description

retract(Clause) erases the first clause of the database that unifies with Clause. The concerned predicate must be a dynamic procedure (section 8.7.1). Removing all clauses of a procedure does not erase the procedure definition. To achieve this use abolish/1 (section 8.7.6). retract/1 is re-executable on backtracking.

Errors

Head is a variable  instantiation_error
Head is neither a variable nor a callable term  type_error(callable, Head)
The predicate indicator Pred of Head is that of a static procedure  permission_error(modify, static_procedure, Pred)

Portability

ISO predicate. In the ISO reference, the operation associated with the permission_error is access while it is modify in GNU Prolog. This seems to be an error of the ISO reference since for asserta/1 (which is similar in spirit to retract/1) the operation is also modify.

8.7.4  retractall/1

Templates

retractall(+head)

Description

retractall(Head) erases all clauses whose head unifies with Head. The concerned predicate must be a dynamic procedure (section 8.7.1). The procedure definition is not removed so that it is found by current_predicate/1 (section 8.8.1). abolish/1 should be used to remove the procedure (section 8.7.6).

Errors

Head is a variable  instantiation_error
Head is not a callable term  type_error(callable, Head)
The predicate indicator Pred of Head is that of a static procedure  permission_error(modify, static_procedure, Pred)

Portability

ISO predicate.

8.7.5  clause/2

Templates

clause(+head, ?callable_term)

Description

clause(Head, Body) succeeds if there exists a clause in the database that unifies with Head :- Body. The predicate in question must be a public procedure (section 8.7.1). Clauses are delivered from the first to the last. This predicate is re-executable on backtracking.

Errors

Head is a variable  instantiation_error
Head is neither a variable nor a callable term  type_error(callable, Head)
The predicate indicator Pred of Head is that of a private procedure  permission_error(access, private_procedure, Pred)
Body is neither a variable nor a callable term  type_error(callable, Body)

Portability

ISO predicate.

8.7.6  abolish/1

Templates

abolish(+predicate_indicator)

Description

abolish(Pred) removes from the database the procedure whose predicate indicator is Pred. The concerned predicate must be a dynamic procedure (section 8.7.1).

Errors

Pred is a variable  instantiation_error
Pred is a term Name/Arity and either Name or Arity is a variable  instantiation_error
Pred is neither a variable nor a predicate indicator  type_error(predicate_indicator, Pred)
Pred is a term Name/Arity and Arity is neither a variable nor an integer  type_error(integer, Arity)
Pred is a term Name/Arity and Name is neither a variable nor an atom  type_error(atom, Name)
Pred is a term Name/Arity and Arity is an integer < 0  domain_error(not_less_than_zero, Arity)
Pred is a term Name/Arity and Arity is an integer > max_arity flag (section 8.22.1)  representation_error(max_arity)
The predicate indicator Pred is that of a static procedure  permission_error(modify, static_procedure, Pred)

Portability

ISO predicate.


Copyright (C) 1999-2021 Daniel Diaz Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. More about the copyright
Previous Up Next