I have a knowledge base consisting of a set of rules whose head of each rule performs assert or retract of complex terms when certain conditions occur.
How can I ensure that Id
is incremented with each
assert(term(Id,A,B,C))
?
I have a knowledge base consisting of a set of rules whose head of each rule performs assert or retract of complex terms when certain conditions occur.
How can I ensure that Id
is incremented with each
assert(term(Id,A,B,C))
?
Assuming you don't care about holes in the Id
(which occur when retracting id_person/2
clauses) you could do:
:- dynamic nextID/1. :- dynamic id_person/2. nextID(0). assertz_person(P) :- nextID(I), retract(nextID(I)), I1 is I+1, assertz(nextID(I1)), assertz(id_person(I,P)).
Sample use (works with SWI-Prolog 8.0.0 and SICStus Prolog 4.5.0):
?- id_person(I,P). false. ?- assertz_person(joan), id_person(I,P). I = 0, P = joan. ?- assertz_person(al), assertz_person(ian), id_person(I,P). I = 0, P = joan ; I = 1, P = al ; I = 2, P = ian.
As you're asserting clauses for a term/3
predicate where the first argument is a unique (integer) identifier, there's no need for an auxiliary dynamic predicate to represent the current counter. You can simply do instead:
:- dynamic(term/3).
assert_term(A, B, C) :-
( term(Id, _, _, _) ->
NextId is Id + 1
; NextId is 1
),
asserta(term(NextId, A, B, C)).
The call to asserta/1
will make the latest asserted clause for term/3
to be the first to be retrieved when called, as above, with all arguments unbound, thus providing access to the last count. This solution assumes, however, that the clauses are not being retracted arbitrarily.