Извлечение элементов в Prolog

#list #prolog

#Список #пролог

Вопрос:

Допустим, у меня есть эта база знаний:

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

Как мне создать предикат, который извлекает все ингредиенты для всех шагов рецепта?

Итак, если я создам правило retrieveIngredients(X,Y). и спрошу retrieveIngredients('pancakes',Y). , как я смогу заставить его извлекать Y = ['butter','eggs','flour', 'baking powder']. ?

Ответ №1:

Просто используя findall/3 :

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

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

Если вы хотите выровнять список, добавьте вызов flatten/2 . Если вы хотите удалить дубликаты, добавьте вызов sort/2 . Обратите внимание, что вам нужно переписать baking powder как baking_powder (без пробела) в третьем step/5 факте.

Комментарии:

1. «… baking_powder (без пробела)» или заключите его в одинарные кавычки, 'baking powder' .

2. Большое спасибо. Вы случайно не знаете, как бы вы добавили их в список, если бы они не были списками? Поэтому вместо [[масло, сахар], [яйца], [мука, baking_powder]] Это было бы просто [масло, сахар, яйца, мука, baking_powder] . Заранее спасибо.

3. ^^ он указывает на это: используйте flatten / 2