Remove all asserted facts?

Remove all asserted facts?

Post by news.adelp » Fri, 27 Aug 2004 00:19:57

I want to remove all facts that were instantiated by the assert() statement
(I want to reset the Prolog database). I tried:


But I got an instantiation error. What's the most convenient way to do


Remove all asserted facts?

Post by russell ky » Fri, 27 Aug 2004 13:25:59

You probably need to keep track of which facts you're likely to assert
and what they look like, in order to be completely portable.

retractall/1 needs the form of the fact to be deleted. "_" isn't a term.

You could try some horrible rubbish like:

:- clause(Foo,true),
functor(Foo,F,N), functor(Bar,F,N),

Or perhaps check whether the "dynamic" predicates of your implementation
can be queried and use that istead of clause/2 -- which will probably
delete too much.

SDF Public Access UNIX System -


Remove all asserted facts?

Post by ptara » Sat, 28 Aug 2004 05:14:07

In systems with multiple dynamic databases like BinProlog or Jinni
you can use operations like *db_clean(DataBaseName)* to achieve this
efficiently. In any case, using *abolish* is faster than *retractall*
which has to linearly scan all clauses - not a very smart thing given
that you want all of them removed! Having to keep track of your
asserted predicates is clearly no fun - you might want to use things
like *current_predicate* for doing this automatically - but again,
adds unpleasant complexity, performace hits and/or non-portability
to your code.

Paul Tarau

New Jinni3D Prolog toolkit with high-level agent oriented
API, supporting morphing, 3D-avatar animation, 3D-graph layout
and more - is now available from

Remove all asserted facts?

Post by Bart Demoe » Sat, 28 Aug 2004 05:50:23

The use of db_clean/1 introduces non-portability with 100% certainty.

On the other hand, I suppose that the db_* family of predicates that
BinProlog supports can be written in ISO Prolog without any complexity
added. Maybe you can post such an implementation: I think that's what
the OP is really after.

A goal like ?- retractall(foo(_)). does NOT need to linearly scan all
clauses and a decent implementation of retractall/1 should exploit this,
by doing the same action as for ?- abolish(foo/1). except forgetting
that foo/1 was ever a dynamic predicate.

> Having to keep track of your

Since current_predicate/1 is an ISO pred, I don't see how it would
introduce non-portability. (not that I think that ISO has defined
current_predicate/1 in a good way, but it is defined)

Whether its usage introduces a performance hit is another kettle of
fish, but performance hits usually come from badly implemented builtins
(rather than their nature) and/or bad program design.


Bart Demoen

Remove all asserted facts?

Post by Jan Wielem » Sat, 28 Aug 2004 05:56:09

abolish does something differently. It not only removes the clauses, but
also the dynamic aspect of the predicate. This is generally not what you
want. Actually ISO abolish/1 is pretty broken as it is not needed for
dynamic clauses and does not work on static ones. I do not see the
performance penalty. retractall/1 can check that the head is completely
unbound and in that case use the same algorithm as abolish to get rid of
the clauses (ok, this is a little bit tricky as retractall(foo(X,X))
cannot use the simple wipe-all strategy).

It is a real FAQ question, but as you say there is not a very clean and
portable solution. On most systems providing modules you can easily
create something along your db_clean/1 by removing the dynamic
predicates in a certain module. The following should work for SWI-Prolog
and I think also for Quintus, SICStus, Ciao and maybe a few more.

db_clean(Module) :-
forall(predicate_property(Module:Head, dynamic),


--- Jan

Remove all asserted facts?

Post by vannoor » Sat, 28 Aug 2004 06:36:22

i wouldn't be worried by both "complexity" and "performance hits" in
this context. And non-portability would be an issue only if there is
a portable solution.


Gertjan van Noord Alfa-informatica, RUG, Postbus 716, 9700 AS Groningen
vannoord at let dot rug dot nl ~vannoord

Remove all asserted facts?

Post by russell ky » Sat, 28 Aug 2004 12:56:29


A good point. I've even noticed some retract's also do the same.

Remove all asserted facts?

Post by Jan Wielem » Sat, 28 Aug 2004 16:01:57

If the implementation claims compatibility to ISO or some de-facto
standard you should report that as a bug to the implementor.

--- Jan

Remove all asserted facts?

Post by ptara » Sun, 29 Aug 2004 04:45:22


Remove all asserted facts?

Post by ptara » Sun, 29 Aug 2004 05:09:05

While this is all true, the deeper problem is that the Prolog API
handling sets of clauses forming a database (also seen sometime as a
map from functor/arities to actual clause sets) has grown in a very
ad-hoc way for about 20 years or so. Just think about how easy all
this would be if you could look at Prolog sets of clauses the same way
Java programmers look at Collections and Maps. As the original poster
requested - one should be able to empty a database just by saying so -
rather than having to maze through several fairly intricate and
sometime implementation dependent builtins.

Paul Tarau

P.S. I apologize for the empty reply that might have went out before

Remove all asserted facts?

Post by Holger Kan » Mon, 30 Aug 2004 03:39:09

Your db_clean/1 also removes imported predicates, sometimes this is not intended.
The following avoids this.

db_clean(Module) :-
forall((predicate_property(Module:Head, dynamic),
\+ predicate_property(Module:Head, imported_from(_))),


Remove all asserted facts?

Post by Jan Wielem » Tue, 31 Aug 2004 17:23:08


I know/knew :-) I left it out for two reasons. First of all,
predicate_property/2 is supported by a number of Prolog systems,
but the imported_from(Module) property is SWI-Prolog specific and
second some people have claimed (and I agree) than exporting
dynamic predicates isn't really elegant.

Cheers --- Jan