Question

As far as I understand the predicates setof/3 and bagof/3 can be used generate a list of solutions to a problem. (Link to gprolog manual).

As expected the solutions to the following query are a, b and c.

?- nth(_, [a,b,c], X).                 
X = a ? ;
X = b ? ;
X = c ? ;
yes

And now I try this:

?- setof(X, nth(_, [a,b,c], X), ListOfSolutions).
ListOfSolutions = [a] ? ;
ListOfSolutions = [b] ? ;
ListOfSolutions = [c]
yes

The solution should have been [a,b,c] in my opinion. What am I doing wrong?

I am using gprolog 1.4.0 for Mac OS.


Edit: Solution

What I really needed was the (^)/2 operator, but the answer given here was completely correct, thank you very much for your help. If anyone has a similar problem here is my current code to select cells from a 3-dimensional grid.

% selectFLR(?Grid, ?ClassId, ?TDayIdD, ?HourId, -ListOfFLR)
% ---------------------------------------------------------
selectFLR(Grid, ClassId, DayId, HourId, ListOfFLR) :-
    bagof(FLR, ClassId^DayId^HourId^selectSingleFLR(Grid, ClassId, DayId, HourId, FLR), ListOfFLR).

selectSingleFLR(Grid, ClassId, DayId, HourId, FLR) :-
    nth(ClassId, Grid, Class),
    nth(DayId, Class, Day),
    nth(HourId, Day, FLR).
Was it helpful?

Solution

No, it should not. nth(_,[a,b,c],X) gives 1 solution for X every time. setof (and bagof) work like:

setof(Things, GoalCondition, Bag)

If you specify Things as X, and the X from nth/3 is (as you show in the above example) just a single variable each time, setof will just create a list of that single variable. Other possible unifications will be possible, but it will just make a Bag of 1 item that is in Things each time.

Formal: The predicates bagof and setof yield collections for individual bindings of the free variables in the goal. setof yields a sorted version of the collection without duplicates ... findall acts like bagof with all free variables automatically existentially quantified. In addition findall returns an empty list [] there is no goal satisfaction, whereas bagof fails.

To make a long story short: use findall :P

OTHER TIPS

Try writing like this:

findall((A,B,C,D,E), coursemeetings(A,B,C,D,E),L)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top