There are several issues in the code you show.
Bad meta argument
First, the built-in predicate setof/3
has the following properties:
?- predicate_property(setof(A,B,C),P).
P = (meta_predicate setof(?,0,?))
; P = built_in
; P = jittable.
which closely corresponds to the ISO declarations in ISO/IEC 13211-1:
8.10.3.2 Template and modes
setof(?term, +callable_term, ?list)
The second argument is a goal to be executed by call/1
. No extra arguments are needed. This is what the 0
tells us.
On the other hand, your code you show contains a different meta predicate declaration:
:- meta_predicate(set_of(+,:,+)) .
Here, the second argument is a :
. In SICStus, YAP, and SWI, the :
means: This argument will be automatically qualified with the current module, such that the module information can be passed further on. Think of asserta(:)
. Here, the argument is not a goal but a clause.
So what you need to fix this, is to replace :
by 0
. And you might indicate this fact in the variable name used. That is, Goal_0
for call(Goal_0)
, Goal_1
for call(Goal_1, Arg1)
, Goal_2
for call(Goal_2, Arg1, Arg2)
etc.
Bad modes
The +
in the first and third argument is inappropriate. The 3rd argument is commonly an uninstantiated variable to be unified with the resulting list.
Prolog's setof/3
baroque?
% Prologs set_of is baroque
The comment probably wants to say that setof/3
contains superfluous ornaments. In fact, setof/3
is much more versatile than mentioned set_of/3
. Take this recent question or that. Often you first think about a very specific situation. Say, you want the list of actors of a particular movie. Then, later on you want to ask what movies there are. It is this generalization which works very smoothly with setof/3
whereas it is extremely complex if you do not have it.
Another very useful way to use setof/3
is when you want to eliminate redundant answers:
?- (X=2;X=1;X=2).
X = 2
; X = 1
; X = 2.
?- setof(t, (X=2;X=1;X=2), _).
X = 1
; X = 2.
Try to emulate that efficiently.
Runtime overheads
They are next to negligible. If you really believe that there are overheads, simply use setof/3
with a single goal. In this manner preprocessing is next to naught.