序言中的食谱功能

recipe function in prolog

假设您在 prolog 中将菜谱另存为

step(meal name, stepnumber, stepexaplanation, ingredients (list) , utensils). 

因此,对于每个 meal name,您都需要执行多个步骤并提供所有说明来制作这顿饭。那么您将如何创建一个调用 getStepText(X,Y,Z). 的函数?所以如果你问:

?- getStepText('pancakes',2,Y). 

将return正文第二步换成煎饼饭

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

getStepText(Dish,Num,Text):-
    step(Dish, Num, Text, _, _).

?- getStepText('pancakes',2,Y). 
Y = 'add eggs' ;
false.

如果您使用的是 SWI Prolog,则可以使用内置谓词 findall/3 来查找所有步骤。不要忘记对它们进行排序。

getSteps(X,S):- 
    findall(N,step(X,N,_,_,_),Bag), 
    sort(Bag,S). 

?- getSteps('pancakes',Y). 
Y = [1, 2, 3] ;
false.

如果您不想使用 findall/3,您可以定义一个辅助谓词 getSteps/3。此谓词假定所有步骤都是递增的并从 1 开始。

getSteps(X,S):- 
    getSteps(X,S,1).

getSteps(X, [], N):-
    \+ step(X, N, _, _, _). 
getSteps(X, [N|T], N):-
    step(X, N, _, _, _),
    NN is N+1,
    getSteps(X, T, NN).

?- getSteps('pancakes',Y). 
Y = [1, 2, 3] ;
false.

解释:你基本上运行一个计数器N从1(调用时设置)直到你找不到任何与当前数字N相关的步骤。第一条规则测试结束:如果您没有针对当前 N "return" 的步骤,则空列表 [].

否则,当您找到编号为 N 的步骤时,请尝试为下一个值 NN(即 N+1)查找步骤列表 T,并且 -一旦找到 - 将 N 放在列表顶部 T.