Skip to content
assert and retract
step 1/4

Reading — step 1 of 4

Learn

~1 min readPatterns and State

Prolog's database is mutable at runtime. assert adds a clause; retract removes one.

:- dynamic(counter/1).         %% declare counter/1 as modifiable
counter(0).

increment :-
    counter(N),
    N1 is N + 1,
    retract(counter(N)),
    assert(counter(N1)).

?- increment.
?- increment.
?- counter(X).
X = 2.

The :- dynamic(name/arity). directive marks predicates that can be modified at runtime. Without it, assert/retract errors on most engines.

asserta prepends; assertz appends:

asserta(score(alice, 90)).      %% becomes the FIRST score/2
assertz(score(bob, 75)).         %% becomes the LAST

retract(Pattern) — removes ONE matching clause, fails if none. retractall(Pattern) — removes ALL matching clauses, never fails.

Use cases:

  • Memoization (cache results of expensive computations)
  • State accumulation across queries
  • Knowledge base updates from input data

Caveats:

  • Asserted clauses persist across queries — use carefully in libraries
  • Threading / concurrency: Prolog implementations vary; check your engine's docs
  • Performance: dynamic predicates are slower than compiled static ones

Ad-hoc memoization:

:- dynamic(memo/2).

fib(N, F) :-
    memo(N, F), !.            %% cache hit
fib(0, 0).
fib(1, 1).
fib(N, F) :-
    N > 1,
    N1 is N - 1, N2 is N - 2,
    fib(N1, F1), fib(N2, F2),
    F is F1 + F2,
    asserta(memo(N, F)).      %% cache the result

This turns exponential fib into linear.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…