GNU Prolog assert error

2019-01-15 18:43发布

问题:

I am new to Prolog, but I am stuck at this supposedly simple command. I have loaded a knowledge base with no errors, and whenever I try do assert (and even help) I get the following message:

uncaught exception: error(existence_error(procedure,assert/1),top_level/0)
{2}

What am I exactly missing? Appreciated.

回答1:

Use assertz/1 or asserta/1 instead. GNU-Prolog does not provide assert/1 because only asserta/1 and assertz/1 are defined in the standard.

Note that while asserta/1 always had one clear interpretation meaning add the clause at the beginning, the meaning of assertz/1 was more difficult to resolve since "add a clause at the end" does not completely determine the semantics of goals that have been invoked prior to asserting the clause.

With ISO-Prolog, goals that have been invoked prior to assertz/1 (but also retract/1) remain unaffected. This is known as the logical update view. To quote the standard (ISO/IEC 13211-1:1995):

7.5.4 A logical database update

Any change in the database that occurs as the result of
executing a goal (for example, when the activator of a
subgoal is a call of assertz/1 or retract/1) shall affect
only an activation whose execution begins afterwards. The
change shall not affect any activation that is currently
being executed.

NOTE — 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 (see 7.7.7 e).

Note that in DECsystem 10 Prolog, the manual made a big difference between assert/1 and assertz/1. In the following quote from the DECsystem 10 User guide of 1978, the term implementation defined can only mean what is known in the standard as implementation dependent (meaning essentially undefined).

5.5 Meta-Logical

...

assert(C)

The current instance of C is interpreted as a clause and is added
to the current interpreted program (with new private variables
replacing any uninstantiated variables). The position of the new
clause within the procedure concerned is implementation-defined.
C must be instantiated to a non-variable.

asserta(C)

Like assert(C), except that the new clause becomes the first
clause for the procedure concerned.

assertz(C)

Like assert(C), except that the new clause becomes the last
clause for the procedure concerned.

Also today there are systems where assert/1 and assertz/1 differ. E.g., xsb.