I’m not a fan of cuts, so I’d write it:
assert_insect(Insect) :-
assertion(ground(Insect)),
( insect(Insect)
-> true
; assertz(insect(Insect))
).
The assertion/1 is because this code could have unexpected results if Insect
is a term that contains a variable.
Another way of doing this is to add the table/1 directive:
?- dynamic insect/1.
true.
?- table insect/1.
true.
?- assertz(insect(fly)).
true.
?- assertz(insect(flea)).
true.
?- assertz(insect(fly)).
true.
?- bagof(Insect, insect(Insect), Insects).
Insects = [flea, fly].
If the table/1 directive is removed, the bagof/3 query gets Insects = [fly, flea, fly]
.
PS: assert/1 is deprecated and assertz/1 is recommended instead.