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…