Prolog递归查询问题:如何找出隔两位就座的人?
解决Prolog中查找某人右侧两个位置的递归查询问题
嘿,很高兴看到你在探索Prolog里的围坐位置问题!要找出某人右侧两个位置的人,递归是个非常合适的思路——我们可以基于已有的sits_right_of事实,一步步构建通用的递归规则,甚至还能扩展到查找任意N个位置外的人。
第一步:定义通用的递归规则
先写一个能处理任意右侧N个位置的规则,这样不仅能满足当前“两个位置”的需求,以后要找更多位置也能直接复用:
% 终止条件:当N=1时,直接匹配已有的sits_right_of事实 sits_right_n(X, Y, 1) :- sits_right_of(X, Y). % 递归步骤:要找Y右侧N个位置的X,先找到Y右侧1个位置的Z,再找Z右侧N-1个位置的X sits_right_n(X, Y, N) :- N > 1, M is N - 1, sits_right_n(Z, Y, 1), sits_right_n(X, Z, M).
第二步:简化为“右侧两个位置”的专用规则
如果只需要固定找右侧两个位置的人,可以写一个更直观的专用规则,调用上面的通用递归:
% X坐在Y的右侧两个位置 sits_right_two(X, Y) :- sits_right_n(X, Y, 2).
测试示例
假设我们有以下围坐事实(环形或直线都适用,只要sits_right_of正确描述位置关系):
sits_right_of(bob, alice). sits_right_of(charlie, bob). sits_right_of(dave, charlie). % 如果是环形,补充最后一个人的右侧是第一个人: sits_right_of(alice, dave).
现在查询:
sits_right_two(X, alice).会返回X = charlie(alice右边第一个是bob,bob右边第一个是charlie)- 如果是环形,查询
sits_right_two(X, dave).会返回X = bob(dave右边第一个是alice,alice右边第一个是bob)
小提醒:修正你现有规则的小问题
顺便提一句,你写的are_neighbors_of(X, Y, Z)规则和注释描述不符——注释说“X坐在Z的左侧且Y坐在Z的右侧”,但当前规则只判断了sits_left_of(X, Z),应该补充Y的条件:
are_neighbors_of(X, Y, Z) :- sits_left_of(X, Z), sits_right_of(Y, Z).
这样才符合你原本的设计意图哦。
内容的提问来源于stack exchange,提问作者AcidMammoth
相关产品推荐
相关产品推荐

