Prolog遍历规则如何避免嵌套循环 先输出连通房间再输出物品
Prolog 房间查询输出顺序问题修复
问题原因
原有start规则将connected/2和containing/2放在同一条回溯链中,fail触发回溯时会交替匹配两个谓词的解,每找到一个连通房间就会遍历输出一遍所有物品,导致物品重复输出、顺序错乱,无法实现「先输出所有连通房间,再输出所有物品」的需求。
修复代码
核心逻辑是将两个输出逻辑拆成独立的回溯阶段,先通过fail驱动遍历完所有连通房间的解,再进入物品遍历阶段,避免交叉回溯。
room(balcony). room(bedroom). room(kitchen). room(hall). contains(balcony,shoerack). contains(balcony,plants). contains(bedroom,bed). contains(bedroom,wardrobe). contains(kitchen,fridge). contains(kitchen,stove). contains(hall,sofa). contains(hall,tv). door(bedroom,balcony). door(hall,bedroom). door(hall,kitchen). % 打印单条连通房间记录 print_connected(X,Y) :- room(X), room(Y), door(X,Y), write('Connected to: '), write(Y), nl. % 打印单条物品记录 print_item(A,B) :- room(A), contains(A,B), write('Contains Item: '), write(B), nl. input(P) :- write('Enter Place: '), read(P). start :- input(P), % 第一阶段:遍历输出所有连通房间,遍历完成前不会进入下一阶段 (print_connected(P,_), fail; % 第二阶段:连通房间全部输出后,遍历输出所有物品 print_item(P,_), fail; % 遍历完成后返回true,避免最终返回false true).
可选优化
如果需要门是双向连通(例如在阳台也能查询到连通卧室),只需要在door事实下方添加对称规则即可:
door(X,Y) :- door(Y,X).
运行效果
输入hall时的输出如下,完全符合顺序要求,无重复内容:
Enter Place: hall. Connected to: bedroom Connected to: kitchen Contains Item: sofa Contains Item: tv true.
内容的提问来源于stack exchange,提问作者Harsh
相关产品推荐
相关产品推荐

