Swi Prolog, unloading source files
Asked Answered
C

4

6

Is there a built-in predicate or a easy way to remove from the knowledge database of prolog a source files that has already been consulted? I've gone through the reference manual and didn't find any thing that could do that.

Caterina answered 13/6, 2012 at 20:59 Comment(0)
U
4

You can do it with these procedures which use source_file/1 and source_file/2:

unload_last_source:-
  findall(Source, source_file(Source), LSource),
  reverse(LSource, [Source|_]),
  unload_source(Source).

unload_source(Source):-
  ground(Source),
  source_file(Pred, Source),
  functor(Pred, Functor, Arity),
  abolish(Functor/Arity),
  fail.
unload_source(_).

unload_source/1 abolishes all predicates defined by the input Source file name. Be warned that it needs to be an absolute path.

unload_last_source/0 will retrieve the last consulted file name and unload it.

Unrequited answered 13/6, 2012 at 21:43 Comment(2)
There several implementations of Prolog. The OP makes no mention of the Prolog system(s) he is using. This solution works on SWI-Prolog. It will not work in most other Prolog compilers, which don't provide the source_file/1-2 built-in predicates and/or allow static predicates to be abolished. Solutions that are dependent on a particular Prolog implementation are best explicitly marked as such.Cecil
@Paulo Moura: the OP tagged the question as SWI-Prolog specific. The answer instead lacks to note that abolish works without accounting of source file...Catenoid
C
1

After a file has been consulted, it become 'irrelevant' to Prolog. So I think that generally to answer should be no. But SWI-Prolog has a rich set of builtins that allows you to control your prolgram. For instance

?- [stackoverflow].

?- predicate_property(P, file('/home/carlo/prolog/stackoverflow.pl')).
P = yield(_G297, _G298) ;
P = now _G297 ;
P = x(_G297) ;
...

?- abolish(yield/2).
true.

?- predicate_property(P, file('/home/carlo/prolog/stackoverflow.pl')).
P = now _G297 ;
P = x(_G297) ;
...

Note that abolish doesn't require the file name to work, you could delete predicates loaded from other sources files.

clause, clause_property and erase should give more control, but I get an error I don't understand (it's undocumented) when attempting to use erase:

?- clause(strip_spaces(_G297, _G298),X,Y),erase(Y).
ERROR: erase/1: No permission to clause erase `<clause>(0x29acc30)'
Catenoid answered 13/6, 2012 at 21:51 Comment(0)
C
0

if you know the name of the predicate, for example fact/2, you can use:

retractall(fact(_,_)).
Carthage answered 13/6, 2012 at 22:24 Comment(2)
applies only to dynamic predicates, i.e. ones set with assert, right?Voyeurism
Indeed it does only apply to dynamic predicates, but they do not have to have been asserted at runtime, the can also have been declared in the source file.Carthage
E
0

This will work.

unload_file(+File)

Remove all clauses loaded from File. If File loaded a module, clear the module's export list and disassociate it from the file. File is a canonical filename or a file indicator that is valid for load_files/2. This predicate should be used with care. The multithreaded nature of SWI-Prolog makes removing static code unsafe. Attempts to do this should be reserved for development or situations where the application can guarantee that none of the clauses associated to File are active.

Entomo answered 4/8, 2021 at 0:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.