【发布时间】:2021-04-06 12:08:04
【问题描述】:
我是 Prolog 的新手,在理解我的代码有什么问题时遇到了一些麻烦。
我正在尝试做一个食物推荐者。基本上,用户输入他们是否想要早餐、午餐或甜点以及他们的口味列表。然后程序计算他们的口味与每种食物的特征之间的匹配次数,并返回匹配最多的食物。
我正在使用递归遍历食物列表,一切都按预期工作,直到它到达带有空食物列表的末尾,然后再次开始填充它,回到问题的初始状态。我不明白为什么程序会这样做,我找不到解决方案。
recommend(breakfast, Tastes, Result) :-
findall(Breakfast, breakfast(Breakfast), Breakfasts),
getBestMatch(Breakfasts, Tastes, Result, -1).
recommend(lunch, Tastes, Result) :-
findall(Lunch, lunch(Lunch), Lunches),
getBestMatch(Lunches, Tastes, Result, -1).
recommend(dessert, Tastes, Result) :-
findall(Dessert, dessert(Dessert), Desserts),
getBestMatch(Desserts, Tastes, Result, -1).
% Recursive predicate. Goes through the list of food and calls the matches predicate to count the
% matches and compares it to the current best match. When the food list is empty, it should stop.
% Result should be the name of the best matching food. I think here's where the error is.
getBestMatch([], _, _, _).
getBestMatch([H|T], Tastes, Result, BestMatch) :-
matches(H, Tastes, Matches),
Matches > BestMatch
-> getBestMatch(T, Tastes, H, Matches)
; getBestMatch(T, Tastes, Result, BestMatch).
% Counts the number of matches between the food's characteristics and the tastes.
matches(Food, Tastes, Matches) :-
characteristics(Food, Characteristics),
intersection(Tastes, Characteristics, MatchList),
length(MatchList, Matches).
% These are some examples of how I have declared the food and its characteristics
lunch(lasagna).
lunch(pizza).
dessert(cake).
characteristics(lasagna, [warm, salty, pasta, italian, meat]).
characteristics(pizza, [warm, salty, cheese, italian]).
characteristics(cake, [cold, sweet, vegetarian]).
这是跟踪的片段。
Call: (12) getBestMatch([pizza], [italian, cheese], lasagna, 1) ? creep
Call: (13) matches(pizza, [italian, cheese], _4220) ? creep
Call: (14) characteristics(pizza, _4262) ? creep
Exit: (14) characteristics(pizza, [warm, salty, cheese, italian]) ? creep
Call: (14) lists:intersection([italian, cheese], [warm, salty, cheese, italian], _4376) ? creep
Exit: (14) lists:intersection([italian, cheese], [warm, salty, cheese, italian], [italian, cheese]) ? creep
Call: (14) length([italian, cheese], _4474) ? creep
Exit: (14) length([italian, cheese], 2) ? creep
Exit: (13) matches(pizza, [italian, cheese], 2) ? creep
Call: (13) 2>1 ? creep
Exit: (13) 2>1 ? creep
Call: (13) getBestMatch([], [italian, cheese], pizza, 2) ? creep
Exit: (13) getBestMatch([], [italian, cheese], pizza, 2) ? creep
Exit: (12) getBestMatch([pizza], [italian, cheese], lasagna, 1) ? creep
Exit: (11) getBestMatch([lasagna, pizza], [italian, cheese], _2882, -1) ? creep
Exit: (10) recommend(lunch, [italian, cheese], _2882) ? creep
true.
我尝试过查看类似的问题,但没有一个对我有用。
PS:对不起,如果这个问题或代码示例太大,这是我在这里的第一个问题,我无法弄清楚如何进一步简化它。
【问题讨论】:
-
说
listing(getBestMatch)查看问题 -
否则,一个可重现的案例会有所帮助。