从Prolog中的列表创建子列表

时间:2016-11-04 15:49:20

标签: list prolog

我无法理解prolog中的概念。

我有一个序言:

MyList = [item(dog,red), item(cat,black), item(rat,gray)]

我希望创建一个只有颜色的列表,即 [red,black,gray]

目前我尝试的解决方案是:

getlistcolors([item(_,C)|T], Result) :-
    getlistcolors(T,Result),
    append([C],Result,Result).

getlistcolors([],_).

我希望能够调用该函数:

?- getlistcolors(MyList, Result).
Result = [red,black,gray]

感谢任何帮助。

由于

2 个答案:

答案 0 :(得分:2)

尝试

getlistcolors([], []).

getlistcolors([item(_,C)|T], [C | Result]) :-
    getlistcolors(T,Result).

您无法使用

附加新的C颜色
append([C],Result,Result)

因为您要确认第二个列表和附加列表是等于。

你应该使用两个不同的变量写

getlistcolors([item(_,C)|T], Result) :-
    getlistcolors(T,HeadC),
    append([C],HeadC,Result).

但您可以获得前置 - C效果,只需将C翻译为第二个参数的头部

getlistcolors([item(_,C)|T], [C | Result]) :-

您的代码的第二点错误:终端子句不能写为

getlistcolors([], _).

或第二个论点不与[]统一,而且结果变得类似

[red,black,gray|_20]

其中_20是一个不统一的变量。

答案 1 :(得分:1)

只是为了解决潜伏者评论中的问题:

使用setof / 3或bagof / 3时,您必须指定'通用量化'在查询中涉及的每个变量中,您对以下内容不感兴趣:

?- 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].

inline documentation

的bagof部分更好地解释了缺失的量化问题

SWI-Prolog解决方案可以使用库yall并应用(两者都自动加载,你不必担心包含它们):

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].