1

Say I have this knowledge base:

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 baking powder', [flour, baking powder], []).

How do I make a predicate that retrieves all the ingredients for all the steps of the recipe?

So if I would make a rule retrieveIngredients(X,Y). and ask retrieveIngredients('pancakes',Y)., how would I be able to make it retrieve Y = ['butter','eggs','flour', 'baking powder'].?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Coderman
  • 159
  • 9

1 Answers1

3

Simply using findall/3:

retrieveIngredients(R,Y):-
    findall(A,step(R,_,_,A,_),Y).

?- retrieveIngredients('pancakes',Y).
Y = [[butter, sugar], [eggs], [flour, baking_powder]]

If you want to get the list flattened, add a call to flatten/2. If you want to remove duplicates, add a call to sort/2. Note that you need to rewrite baking powder as baking_powder (without space) in the third step/5 fact.

damianodamiano
  • 2,528
  • 2
  • 13
  • 21
  • 2
    "... `baking_powder` (without space)" or enclose it in single quotes, `'baking powder'`. – Will Ness Nov 19 '20 at 15:19
  • Thanks a lot. Do you happen to know how you would add them to the list without them being lists? So instead of [[butter, sugar], [eggs], [flour, baking_powder]] It would just be [butter, sugar, eggs, flour, baking_powder]. Thanks in advance. – Coderman Nov 19 '20 at 16:03
  • ^^ he statet it: use flatten/2 – DuDa Nov 19 '20 at 19:34