Better to use bagof/3
or setof/3
. As Lee Naish and Richard O’Keefe have pointed out, findall
is unsound if the Template doesn’t capture all the free variables in the Goal.
bagof
and setof
allow you to mark variables as existentially qualified (although you might want to define an auxiliary predicate for clarity), and also allow backtracking over the other free variables. The downside of using bagof
and setof
is that if you want “no solutions” to result in []
, you need to wrap it: (bagof(X, pred(X), Results) -> true ; Results=[])
.