I want to retract fact, but I have not direct access to the name of fact. To get anything from this fact I'd use following code:
facts.pl file:
:- dynamic fact/2.
fact(a, b).
fact(b, e).
fact(a, c).
fact(e, d).
fact(c, d).
fact(d, f).
fact(d, g).
solution.pl file:
someProcedure(StructureName) :-
call(StructureName, a, X).
Now how could I retract that dynamic fact from memory in solution.pl?
I've tried something like:
deleteProcedure(StructName, A, B) :-
retract(call(StructName, A, B)).
But I get error:
ERROR: retract/1: No permission to modify static procedure `call/3'
ERROR: Defined at /usr/lib/swi-prolog/boot/init.pl:217
You can use the univ predicate (=../2) to build the term to retract.
retract_fact(Name, A, B) :-
Fact =.. [Name,A,B],
retract(Fact).
Note this solution accepts only atoms as the Name, so it is tailored to your example:
?- retract_fact(fact,a,b).
true.
and will not work if you pass a compound term, e.g.:
:- dynamic fact/3.
fact(a, b, c).
?- retract_fact(fact(a),b,c).
ERROR: Type error: `atom' expected, found `fact(a)' (a compound)
Here is a revised solution accepting compound terms:
retract_fact(Term, A, B) :-
Term =.. L,
append(L, [A,B], L1),
Fact =.. L1,
retract(Fact).
Sample run:
?- retract_fact(fact(a),b,c).
true.
?- retract_fact(fact,b,e).
true.