I need an ordered list of Objects that satisfy Goal. setof takes care of the ordering, but fails when no Objects satisfy Goal. I want to return an empty list instead like findall does.
This works, but is there a way of accomplishing this without a cut? I'm using SWI-Prolog.
setof(Object, Goal, List), !; List = [].
First,
does not work, as you suggest. It always succeeds for
List = [], and it only shows the first answer ofsetof/3. Butsetof/3may produce several answers. The general method that works in any Prolog is:Many implementations offer an implementation specific control construct for this which avoids that
Goalis called twice. E.g.if/3(SICStus, YAP), or(*->)/2(SWI, GNU):The new variable
ListXis necessary for the (admittedly rare) case thatListis already instantiated.Note that both other answers do not produce exactly what you asked for.