Use setof/3 when goal not exported from module with existential (caret) operator (^)

For a goal like my_goal(A,B,C) in module my_module but with my_goal/3 not exported and wanting to collect just C into a set.

setof(C,[A,B]^(my_module:my_goal(A,B,C)),Set).

Notes

This was the way I originally posted this, which is wrong.

setof(C,my_module:[A,B]^my_goal(A,B,C),Set).

Then Jan W. gave the correct way.


Also see this SO question.

setof(C,[A,B]^(my_module:my_goal(A,B,C)),Set).
1 Like

Thanks,

Is that a better way, a preferred way, or just another way?

The reason I posted it was because I don’t know of an example with all of these requirements:

  1. Use a goal
  2. Use an existential operator (^)
  3. Use more than one existential variable
  4. Use a module qualifier

It is the way. The setof/3 goal argument is of the shape TermWithExistentialVars^Goal. This means the qualifier must be part of Goal. TermWithExistentialVars can be anything. The convention is to use Var1^Var2^Var3^Goal.

1 Like

@EricGT See also the ^ specifier for meta_predicate/1:

This extension is used to denote the possibly ^ -annotated goal of setof/3, bagof/3, aggregate/3 and aggregate/4. It is processed similar to‘0’, but leaving the ^ /2 intact.

That’s how the system would know to call M:setof(A, X^Goal, As) as setof(A, X^(M:Goal), As) rather than setof(A, M:(X^Goal), As).

2 Likes