2

I am retrieving multiple lists from lists and put them into a new list. But I want to make the new list of individual items and not a list with lists. So say I have the list [[a,b],c,[d,e]] I would like to get [a,b,c,d,e]. How do I go about this?

Coderman
  • 159
  • 9

2 Answers2

3

To use an example code snipping from a random question today: assume you have a knowledge base as follows:

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], []). 

And you are interested in all the ingredients for a dish. First idea would be

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

But the problem here is that the ingredients list is nestet. Since flatten/2 is not allowed you now have 2 choices: either flattening your result or to use findall over all ingredients from the ingredientslist of each step for a dish.

For flatten I recomment using the implementation flatten2/2 from this post. The resulting question could be something like this:

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

Add a sort/2 if you want to get rid of duplicates as statet in this post.

If you want to use the second method, you have to create a helper predicate which shows the ingredients for all dishes. ingredients/3 gives the ingredients as single element for each dish and step number. So for each Dish and Step multiple entries with different Ingredients are possible.

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.

To get rid of the duplicates use sort/2.

PS: I still don't know if you are allowed to use findall/3.

DuDa
  • 3,718
  • 4
  • 16
  • 36
1
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.

?- 
Kintalken
  • 763
  • 5
  • 9