在prolog中的新列表中列出,而不使用flash/2



我正在从列表中检索多个列表,并将它们放入一个新列表中。但我想做一个单独项目的新列表,而不是一个有列表的列表。假设我有列表[[a,b],c,[d,e]],我想得到[a,b,c,d,e]。我该怎么做?

要使用今天从一个随机问题中截取的代码示例:假设您有如下知识库:

step('pancakes', 1, 'mix butter and sugar in a bowl', [butter, sugar], [bowl]). 
step('pancakes', 2, 'add eggs', [eggs], []). 
step('pancakes', 3, 'mix flour and bakingpowder', [flour, bakingpowder], []). 

你对一道菜的所有原料都感兴趣。第一个想法是

?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I).
Dish = pancakes,
I = [[butter, sugar], [eggs], [flour, bakingpowder]] ;
false.

但这里的问题是配料表是嵌套的。由于flatten/2是不允许的,您现在有两个选择:要么使结果变平,要么使用findall覆盖一道菜中每个step的成分列表中的所有成分。

对于flatten,我建议使用本文中的实现flatten2/2。由此产生的问题可能是这样的:

?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).

如果你想在这篇文章中消除重复,请添加一个sort/2

如果你想使用第二种方法,你必须创建一个辅助谓词,显示所有菜肴的成分。ingredients/3给出了每道菜的单一元素和步骤编号。因此,对于每个DishStep,具有不同成分的多个条目是可能的。

ingredients(Dish,Step,Ingred):-
step(Dish,Step,_,L,_),
member(Ingred,L).
?- Dish='pancakes', findall(X,ingredients(Dish,_,X),I).
Dish = pancakes,
I = [butter, sugar, eggs, flour, bakingpowder] ;
false.

要清除重复项,请使用sort/2

附言:我还是不知道你是否被允许使用findall/3

flatten(SOURCEs,TARGETs)
:-
phrase(flatten(SOURCEs),TARGETs)
.
flatten([HEAD|TAILs]) --> { is_list(HEAD) } , HEAD , flatten(TAILs) .
flatten([HEAD|TAILs]) --> { + is_list(HEAD) } , [HEAD] , flatten(TAILs) .
flatten([]) --> [] .
/**
?- flatten([[a,b],c,[d,e]],TARGETs) .
TARGETs = [a, b, c, d, e] ;
false.
?- 

最新更新