如何在Prolog中编写规则选取指定事实并返回对应餐品组合
Prolog 实现指定格式输出的
food(X,Y) 规则 实现思路
你需要先按餐次收集主菜和所有配菜,再将收集到的列表格式化为要求的字符串即可,核心分为两步:数据收集、列表转格式化字符串。
完整可运行代码(适配SWI-Prolog)
/* 已有的事实定义 */ course1(lunch, burrito). side(lunch, chips). side(lunch, pop). course1(dinner, pizza). side(dinner, breadsticks). side(dinner, water). /* 核心查询规则 */ food(X, Y) :- % 获取对应餐次的主菜 course1(X, MainDish), % 收集该餐次的所有配菜 findall(SideDish, side(X, SideDish), SideList), % 拼接为主菜在前、配菜在后的完整食物列表 FoodList = [MainDish | SideList], % 将列表转为要求格式的输出字符串 format_food_list(FoodList, Y). /* 辅助谓词:将食物列表转为指定格式字符串 */ % 列表仅有1个元素的边界情况 format_food_list([Item], Res) :- atom_string(Item, Res). % 列表有2个元素的情况 format_food_list([A, B], Res) :- atom_string(A, AStr), atom_string(B, BStr), string_concat(AStr, " and ", Tmp), string_concat(Tmp, BStr, Res). % 列表有3个及以上元素的情况 format_food_list([First | Rest], Res) :- length(Rest, Len), Len >= 2, % 拆分出除最后一个以外的所有元素、最后一个元素 append(HeadItems, [LastItem], Rest), atom_string(First, FirstStr), maplist(atom_string, HeadItems, HeadStrs), atom_string(LastItem, LastStr), % 拼接前半部分逗号分隔的内容 atomics_to_string([FirstStr | HeadStrs], ", ", Prefix), % 如需牛津逗号(最后一个and前加逗号),下行改为 string_concat(Prefix, ", and ", Tmp) string_concat(Prefix, " and ", Tmp), string_concat(Tmp, LastStr, Res).
运行效果
在SWI-Prolog终端中查询:
- 输入
food(lunch, Y).,默认返回结果:Y = "burrito, chips and pop",将辅助谓词的拼接符改为", and "即可匹配要求的burrito, chips, and pop格式。 - 输入
food(dinner, Y).,返回结果:Y = "pizza, breadsticks and water",完全匹配要求。
适配说明
如果你使用的Prolog版本不支持atom_string/atomics_to_string这类字符串处理谓词,替换为对应环境的原子拼接谓词即可,核心逻辑是通用的。
内容的提问来源于stack exchange,提问作者user2355903
相关产品推荐
相关产品推荐

