Reputation: 2647
I am having trouble understanding a concept in prolog.
I have a prolog list:
MyList = [item(dog,red), item(cat,black), item(rat,gray)]
and I am looking to create a list of just the colors i.e.
[red,black,gray]
Currently the solution I have tried is:
getlistcolors([item(_,C)|T], Result) :-
getlistcolors(T,Result),
append([C],Result,Result).
getlistcolors([],_).
I would like to be able to call the function:
?- getlistcolors(MyList, Result).
Result = [red,black,gray]
Any help is appreciated.
Thanks
Upvotes: 0
Views: 504
Reputation: 60034
Just to fix a problem in lurker comment:
when using setof/3 or bagof/3, you have to specify 'universal quantification' of each variable involved in the query, you're not interested in:
?- MyList = [item(dog,red), item(cat,black), item(rat,gray)],setof(Color, P^member(item(P, Color), MyList), ColorList).
MyList = [item(dog, red), item(cat, black), item(rat, gray)],
ColorList = [black, gray, red].
the missing quantification problem is better explained in the bagof section of inline documentation
A SWI-Prolog solution could make use of libraries yall and apply (both autoloaded, you don't have to worry about including them):
getlistcolors(List, Colors) :- maplist([E,C]>>(E = item(_,C)), List, Colors).
?- getlistcolors([item(dog,red), item(cat,black), item(rat,gray)],Cs).
Cs = [red, black, gray].
Upvotes: 1
Reputation: 66230
Try with
getlistcolors([], []).
getlistcolors([item(_,C)|T], [C | Result]) :-
getlistcolors(T,Result).
You can't append the new find C
color with
append([C],Result,Result)
because you're imposign that the second list and the appended list are equals.
You should use two different variables writing
getlistcolors([item(_,C)|T], Result) :-
getlistcolors(T,HeadC),
append([C],HeadC,Result).
but you can obtain the prepend-C
effect simply translating C
as head of the second argument
getlistcolors([item(_,C)|T], [C | Result]) :-
Second point wrong with your code: the terminal clause can't be written as
getlistcolors([], _).
or the second argument isn't unified with []
and the reasult become something like
[red,black,gray|_20]
where _20
is a variable that isn't unified.
Upvotes: 2